在Swift中的元编程

10

作为一个C++程序员,我正在尝试在Swift中进行一些元编程。例如,我想实现一个元函数来添加两个数字。我尝试了以下代码:

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(有时甚至会崩溃)。

如何实现这样的功能?


先生们好,差不多一年过去了,关于Swift和元编程方面有什么新消息吗? - dede.exe
2个回答

8

static 存储属性目前不支持泛型对象。当我把你的代码放到 playground 中时,实际上会出现以下错误:

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
    }
}
注意:由于这是一个计算属性,您需要使用var而不是let来声明value 通过这些更改,println(Sum<A, B>.value)打印出像您预期的那样的12

说实话,我不太确定我想要什么(在语言语义学意义上)。最终目标是,一旦启用所有优化,Sum<A, B>.value 将在生成的二进制代码中被减少为一个常量。 - Yaron Tausky

0

在我看来,你需要匹配你的定义并以不同的方式实现协议。(我不是Swift开发人员,但我在帮助StackOverflow上的人时学习了一些。)

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

你调用了一个 class var,但是你定义了一个 static let。这是微妙的差别,但我认为在这里很重要。

协议不能拥有静态属性,如果您尝试这样做,编译器会抛出错误信息。 - Yaron Tausky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接