在 Swift 中展开两种类型中的一种
Unwrapping either one of two types in Swift
我有一个方法可以对 Swift 中的两种数据执行完全相同的操作。
为了简单起见(并且不重复方法)我将 AnyObject
作为参数传递给我的方法,它可以是这两种类型中的任何一种。如何使用 ||
(OR) 语句解包以便继续?或者这可能是其他方式?
func myFunc(data:AnyObject) {
if let data = data as? TypeOne {
// This works fine. But I need it to look something like unwrapping below
}
if let data = data as? TypeOne || let data = data as? TypeTwo { // <-- I need something like this
// Do my stuff here, but this doesn't work
}
}
我确信这在 Swift 中是微不足道的,我只是不知道如何让它发挥作用。
你不能统一同一事物的两个不同演员表。您必须将它们分开,因为它们是两种不同类型的两种不同类型,编译器需要以两种不同方式处理它们。
var x = "howdy" as AnyObject
// x = 1 as AnyObject
// so x could have an underlying String or Int
switch x {
case let x as String:
print(x)
case let x as Int:
print(x)
default: break
}
如果您有办法将 String 或 Int 传递给它,则可以从这两种不同的情况下调用相同的方法;但这是你能做的最好的了。
func printAnything(what:Any) {
print(what)
}
switch x {
case let x as String:
printAnything(x)
case let x as Int:
printAnything(x)
default: break
}
当然可以问
if (x is String || x is Int) {
但问题是您离执行实际的 cast 还很远。演员表仍需单独执行。
根据 Clashsoft 的评论,我认为协议是解决问题的方法。您可以在两种类型都符合的协议中表示所需的功能,而不是传入 AnyObject 并展开。
这应该会使代码更易于维护,因为您是针对特定行为而不是特定行为进行编码的 类。
我在操场上模拟了一些代码,展示了它是如何工作的。
希望对您有所帮助!
protocol ObjectBehavior {
var nickname: String { get set }
}
class TypeOne: ObjectBehavior {
var nickname = "Type One"
}
class TypeTwo: ObjectBehavior {
var nickname = "Type Two"
}
func myFunc(data: ObjectBehavior) -> String {
return data.nickname
}
let object1 = TypeOne()
let object2 = TypeTwo()
println(myFunc(object1))
println(myFunc(object2))
找出两种类型的共享代码是否完全相同。如果是:
protocol TypeOneOrTypeTwo {}
extension TypeOneOrTypeTwo {
func thatSharedCode() {
print("Hello, I am instance of \(self.dynamicType).")
}
}
extension TypeOne: TypeOneOrTypeTwo {}
extension TypeTwo: TypeOneOrTypeTwo {}
如果没有:
protocol TypeOneOrTypeTwo {
func thatSharedMethod()
}
extension TypeOne: TypeOneOrTypeTwo {
func thatSharedMethod() {
// code here:
}
}
extension TypeTwo: TypeOneOrTypeTwo {
func thatSharedMethod() {
// code here:
}
}
给你:
func myFunc(data: AnyObject) {
if let data = data as? TypeOneOrTypeTwo {
data.thatSharedCode() // Or `thatSharedMethod()` if your implementation differs for types.
}
}
你的意思是这样?
enum IntOrString {
case int(value: Int)
case string(value: String)
}
func parseInt(_ str: String) -> IntOrString {
if let intValue = Int(str) {
return IntOrString.int(value: intValue)
}
return IntOrString.string(value: str)
}
switch parseInt("123") {
case .int(let value):
print("int value \(value)")
case .string(let value):
print("string value \(value)")
}
switch parseInt("abc") {
case .int(let value):
print("int value \(value)")
case .string(let value):
print("string value \(value)")
}
输出:
int value 123
string value abc
我有一个方法可以对 Swift 中的两种数据执行完全相同的操作。
为了简单起见(并且不重复方法)我将 AnyObject
作为参数传递给我的方法,它可以是这两种类型中的任何一种。如何使用 ||
(OR) 语句解包以便继续?或者这可能是其他方式?
func myFunc(data:AnyObject) {
if let data = data as? TypeOne {
// This works fine. But I need it to look something like unwrapping below
}
if let data = data as? TypeOne || let data = data as? TypeTwo { // <-- I need something like this
// Do my stuff here, but this doesn't work
}
}
我确信这在 Swift 中是微不足道的,我只是不知道如何让它发挥作用。
你不能统一同一事物的两个不同演员表。您必须将它们分开,因为它们是两种不同类型的两种不同类型,编译器需要以两种不同方式处理它们。
var x = "howdy" as AnyObject
// x = 1 as AnyObject
// so x could have an underlying String or Int
switch x {
case let x as String:
print(x)
case let x as Int:
print(x)
default: break
}
如果您有办法将 String 或 Int 传递给它,则可以从这两种不同的情况下调用相同的方法;但这是你能做的最好的了。
func printAnything(what:Any) {
print(what)
}
switch x {
case let x as String:
printAnything(x)
case let x as Int:
printAnything(x)
default: break
}
当然可以问
if (x is String || x is Int) {
但问题是您离执行实际的 cast 还很远。演员表仍需单独执行。
根据 Clashsoft 的评论,我认为协议是解决问题的方法。您可以在两种类型都符合的协议中表示所需的功能,而不是传入 AnyObject 并展开。
这应该会使代码更易于维护,因为您是针对特定行为而不是特定行为进行编码的 类。
我在操场上模拟了一些代码,展示了它是如何工作的。
希望对您有所帮助!
protocol ObjectBehavior {
var nickname: String { get set }
}
class TypeOne: ObjectBehavior {
var nickname = "Type One"
}
class TypeTwo: ObjectBehavior {
var nickname = "Type Two"
}
func myFunc(data: ObjectBehavior) -> String {
return data.nickname
}
let object1 = TypeOne()
let object2 = TypeTwo()
println(myFunc(object1))
println(myFunc(object2))
找出两种类型的共享代码是否完全相同。如果是:
protocol TypeOneOrTypeTwo {}
extension TypeOneOrTypeTwo {
func thatSharedCode() {
print("Hello, I am instance of \(self.dynamicType).")
}
}
extension TypeOne: TypeOneOrTypeTwo {}
extension TypeTwo: TypeOneOrTypeTwo {}
如果没有:
protocol TypeOneOrTypeTwo {
func thatSharedMethod()
}
extension TypeOne: TypeOneOrTypeTwo {
func thatSharedMethod() {
// code here:
}
}
extension TypeTwo: TypeOneOrTypeTwo {
func thatSharedMethod() {
// code here:
}
}
给你:
func myFunc(data: AnyObject) {
if let data = data as? TypeOneOrTypeTwo {
data.thatSharedCode() // Or `thatSharedMethod()` if your implementation differs for types.
}
}
你的意思是这样?
enum IntOrString {
case int(value: Int)
case string(value: String)
}
func parseInt(_ str: String) -> IntOrString {
if let intValue = Int(str) {
return IntOrString.int(value: intValue)
}
return IntOrString.string(value: str)
}
switch parseInt("123") {
case .int(let value):
print("int value \(value)")
case .string(let value):
print("string value \(value)")
}
switch parseInt("abc") {
case .int(let value):
print("int value \(value)")
case .string(let value):
print("string value \(value)")
}
输出:
int value 123
string value abc