8

我想为我的项目创建一个这样的方法:

func print(obj: AnyObject) {
    if let rect = obj as? CGRect {
        println(NSStringFromCGRect(rect))
    }
    else if let size = obj as? CGSize {
        println(NSStringFromCGSize(size))
    }

    //...
}

但我不能因为CGRectand CGSizeare structs 并且不符合AnyObject protocol. 那么,关于如何做到这一点的任何想法?

4

4 回答 4

10

使用Any而不是AnyObject.

Swift 提供了两个特殊的类型别名来处理非特定类型:

AnyObject可以表示任何类类型的实例。
Any可以表示任何类型的实例,包括函数类型。

Swift 编程语言

于 2015-04-01T13:19:14.000 回答
5

@nkukushkin 的答案是正确的,但是,如果您想要的是一个行为不同的函数,具体取决于它是通过 aCGRect还是 a CGStruct,那么重载会更好:

func print(rect: CGRect) {
    println(NSStringFromCGRect(rect))
}

func print(size: CGSize) {
    println(NSStringFromCGSize(size))
}

相比之下,这Any既是低效的(将你的结构Any来回转换,如果你在一个紧密的循环中做很多事情,可能会产生很大的影响)和非类型安全的(你可以将任何东西传递给那个函数,它只会在运行时失败)。

如果您的意图是将两种类型强制转换为通用类型,然后对其执行相同的操作,则可以创建采用该类型的第三个重载,并让其他两个调用它。

于 2015-04-01T13:25:47.233 回答
2

刚刚发现了一个更好的方法来做到这一点。Swift 有一个叫做dump的方法,它可以处理很多类型的数据。

例如:

dump(CGRectMake(0, 5, 30, 60))

将打印:

{x 0 y 5 w 30 h 60}
于 2015-04-03T14:54:24.897 回答
1

如果您只需要打印CGRector CGSize,您可以使用:

println(rect)

或者

println(size)

您在函数末尾留下了“...”,因此我假设您需要打印更多类型。为此,您需要使这些类型符合Printable协议(除非它们已经这样做)。这是一个如何 -

class Car { 
    var mileage = 0
}

extension Car : Printable {
    var description: String { 
        return "A car that has travelled \(mileage) miles."
    }
}

您可以使用:

let myCar = Car()
println(myCar)

此外,您可能希望更改当前打印类型的方式的格式。例如,如果您想要println(aRect)与返回的格式相同,NSStringFromCGRect可以使用扩展名:

extension CGRect : Printable {
    public var description: String {
        return "{\(origin.x), \(origin.y)}, {\(size.width), \(size.height)}"
    }
}
于 2015-04-03T16:47:07.930 回答