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

时间:2021-09-25 16:12:31

I know that we can essentially specify that our generics be any reference type by using AnyObject:

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

class Foo<T: AnyObject> {
    // ...
}

But is there a way to specify that our generics should only be value types, and not allow reference types?

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

1 个解决方案

#1


3  

// 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

Solution 1 via 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

But as mentioned in the comments, it is working but not feasible, because user defined value types have to implement this protocol.

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


Solution 2 via method signature

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

func printT <T: Any> (input: T) {
    println("\(input) is value")
}

Solution 3 via assert

Another solution could be via assert

另一个解决方案可能是断言

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

"Solution" 4 via where clauses

This would be the best solution, I think. Unfortunately, it is not possible to have

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

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

or similar. Maybe it will be possible in future releases of Swift.

或类似的。也许在未来的Swift版本中它是可能的。

#1


3  

// 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

Solution 1 via 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

But as mentioned in the comments, it is working but not feasible, because user defined value types have to implement this protocol.

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


Solution 2 via method signature

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

func printT <T: Any> (input: T) {
    println("\(input) is value")
}

Solution 3 via assert

Another solution could be via assert

另一个解决方案可能是断言

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

"Solution" 4 via where clauses

This would be the best solution, I think. Unfortunately, it is not possible to have

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

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

or similar. Maybe it will be possible in future releases of Swift.

或类似的。也许在未来的Swift版本中它是可能的。