我可以指定泛型是值类型吗?

nhg*_*rif 16 generics value-type reference-type swift

我知道我们可以通过使用AnyObject以下方式指定我们的泛型是任何引用类型:

class Foo<T: AnyObject> {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但有没有办法指定我们的泛型应该只是类型,而不允许引用类型?

Mic*_*ner 5

// some code for testing    
class C { } // just a simple class as an example for a reference type
var c = C()
var d: Double = 0.9 // a value type
Run Code Online (Sandbox Code Playgroud)

解决方案 1 通过 extension

protocol ValueType { }
extension Double : ValueType { }
extension Int : ValueType { }
// ... all value types to be added

func printT1 <T: ValueType> (input: T) {
    println("\(input) is value")
}
printT1(d) // Does work
//printT1(c) // Does not work
Run Code Online (Sandbox Code Playgroud)

但是正如评论中提到的,它是有效的但不可行,因为用户定义的值类型必须实现这个协议。


通过方法签名的解决方案2

func printT <T: AnyObject> (input: T) {
    println("\(input) is reference")
}

func printT <T: Any> (input: T) {
    println("\(input) is value")
}
Run Code Online (Sandbox Code Playgroud)

解决方案 3 通过 assert

另一种解决方案可能是通过 assert

func printT <T: Any> (input: T) {
    print("\(input) is " + ((T.self is AnyObject) ? "reference" : "value"))
}
Run Code Online (Sandbox Code Playgroud)

“解决方案” 4 viawhere子句

我认为这将是最好的解决方案。不幸的是,这是不可能的

func printT <T: Any where T: ~AnyObject > (input: T) {
    println("\(input) is value")
}
Run Code Online (Sandbox Code Playgroud)

或类似。也许在 Swift 的未来版本中可以实现。

  • *“Equatable 协议,用于值类型,而 Comparable 协议用于引用类型”* - 我不这么认为。Equatable 意味着您可以使用 `==` 检查“相等”,而 Comparable 意味着 - 此外 - 使用 `&lt;` 有一个严格的顺序。这与值与引用类型无关。(例如,NSObject 是一个引用类型,符合 Equatable。) (5认同)