Метапрограммирование в Swift

Исходя из С++, я пытаюсь выполнить метапрограммирование в Swift. Например, я хотел бы реализовать metafunction, который добавляет два числа. Я пробовал что-то вроде этого:

protocol IntWrapper {
    class var value: Int { get }
}

struct A: IntWrapper {
    static let value = 5
}

struct B: IntWrapper {
    static let value = 7
}

struct Sum<T: IntWrapper, U: IntWrapper>: IntWrapper {
    static let value = T.value + U.value
}

Это, однако, не работает: Xcode жалуется, что T.Type не имеет члена value (или просто падает, иногда.)

Как реализовать такую ​​функциональность?

Ответ 1

static сохраненные свойства не поддерживаются (в настоящее время) на общих объектах. Когда я помещаю ваш код на площадку, я действительно получаю эту ошибку:

Playground execution failed: <EXPR>:23:5: error: static variables not yet supported in generic types
    static let value = T.value + U.value
    ^~~~~~

Вы можете обойти это, используя вместо этого вычисленное свойство (возможно, это было то, что вы хотели в первую очередь):

struct Sum<T: IntWrapper, U: IntWrapper>: IntWrapper {
    static var value: Int {
        return T.value + U.value
    }
}

Примечание:. Поскольку это вычисленное свойство, вам нужно объявить value с помощью var, а не let.

С этими изменениями println(Sum<A, B>.value) печатает 12, как вы ожидали.

Ответ 2

Мне кажется, что вам нужно сопоставить свои определения и реализовать протокол по-разному. (Я не быстрый разработчик, но я учился, когда помогаю людям в stackoverflow.)

protocol IntWrapper {
  static var value : Int { get }
}
struct A: IntWrapper {
  static var value : Int { get { 5 } }
}

Вы вызывали class var, но тогда вы определили static let. Тонкая разница, но я думаю, что это имеет значение здесь.