Могу ли я указать, что общий тип является типом значения?

Я знаю, что мы можем по существу указать, что наши дженерики являются любым ссылочным типом, используя AnyObject:

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

Но есть ли способ указать, что наши дженерики должны быть только значение, а не разрешать типы ссылок?

Ответы

Ответ 1

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

Решение 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

Но, как упоминалось в комментариях, он работает, но не представляется возможным, потому что пользовательские типы значений должны реализовать этот протокол.


Решение 2 с помощью сигнатуры метода

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

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

Решение 3 через assert

Другим решением может быть assert

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

"Решение" 4 через where предложения

Это было бы лучшим решением, я думаю. К сожалению, невозможно

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

или аналогичный. Возможно, это будет возможно в будущих выпусках Swift.