3

我有一个方法可以对 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 中是微不足道的,我只是不知道如何让它工作。

4

4 回答 4

2

你不能统一同一事物的两个不同的演员表。您必须将它们分开,因为它们是两种不同类型的两种不同类型,编译器需要以两种不同的方式处理它们。

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) {

但问题是你离真正的演员还差得远。演员仍然必须单独进行。

于 2015-07-28T19:06:03.740 回答
1

基于 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))
于 2015-07-28T19:32:53.700 回答
0

你的意思是这样吗?

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
于 2020-10-06T19:24:17.007 回答
0

Find if that shared code is exactly the same for both types. If yes:

protocol TypeOneOrTypeTwo {}

extension TypeOneOrTypeTwo {

    func thatSharedCode() {

        print("Hello, I am instance of \(self.dynamicType).")
    }
}

extension TypeOne: TypeOneOrTypeTwo {}
extension TypeTwo: TypeOneOrTypeTwo {}

If not:

protocol TypeOneOrTypeTwo {

    func thatSharedMethod()
}

extension TypeOne: TypeOneOrTypeTwo {

    func thatSharedMethod() {

        // code here:
    } 
}

extension TypeTwo: TypeOneOrTypeTwo {

    func thatSharedMethod() {

        // code here:
    } 
}

And here you go:

func myFunc(data: AnyObject) {

    if let data = data as? TypeOneOrTypeTwo {

        data.thatSharedCode() // Or `thatSharedMethod()` if your implementation differs for types.
    }
}
于 2016-03-30T14:13:51.307 回答