具有泛型类型的属性

时间:2018-02-16 15:51:24

标签: ios swift generics

是否可以使用泛型类型的属性?

我想做什么:

有一个名为Value的基类,其结构如下:

class Value {
  var genericProperty: T

  init<T>(type: T) {
      switch type.self {
      case is Int.Type:
        genericProperty is Int
      case is [Int.Type]:
        genericProperty is [Int]
      default:
        genericProperty is Any
      }
  }
}

然后有一堆子类来定义genericProperty的类型。

这样的事情:

class IntValue: Value {
  override init<T>(type: T) {
      super.init(type: Int.self)
  }
}

class IntArrayValue: Value {
  override init<T>(type: T) {
      super.init(type: [Int.self])
  }
}

associatedType或其他任何类型都可能以某种方式实现吗?

澄清(可能这个设计很糟糕)。我想沿着这条线做点什么:

func handle(values: [Value]) {
  values.forEach {
    switch $0 {
      case is IntValue.Type:
        // Here I will now know that `genericProperty` will have type `Int` 
        // and can assign to a property with `Int` type

        property: Int = $0.genericProperty
      case is IntArrayValue.Type:
        // Here I know it will be an array
      ...
    }
  }
}

2 个答案:

答案 0 :(得分:2)

不确定这是否是您要找的,但是......您可以创建一个通用基类并添加指定具体类型的子类:

class Value<T> {
  var value: T
  init(_ value: T) {
    self.value = value
  }
}

现在有一些具有特定值类型的子类:

class IntValue: Value<Int> {}
class StringValue: Value<String> {}

以下是如何使用它们:

let intValue = IntValue(42)
intValue.value // 42

let stringValue = StringValue("Hi")
stringValue.value // "Hi"

答案 1 :(得分:0)

一般来说答案是否定的。

在您的示例中,genericProperty在超类的子类中将具有不同的类型,这将破坏类型系统。如果你能做到,那么你可以合法地尝试这样的事情:

var array: [Value] = []
array.append(IntValue())
array.append(FloatValue())

for v in array
{
    let foo = v.genericProperty
}

编译器应该推断出foo的类型?