Swift - 如何创建自定义运算符以在其他模块中使用?

时间:2014-11-20 20:39:57

标签: swift operators

我创建了一个示例项目和旁边的框架。该框架称为“SampleFramework”。然后我在SampleFramework中创建了一个自定义运算符。这是它的样子:

infix operator >>= {associativity left}
public func >>=<A, B>(a: A?, f: A -> B?) -> B? {
    if let a = a { return f(a) }
    else { return .None }
}

然后我想用它作为我的主要应用程序。我将SampleFramework导入到我的源文件中,然后我编写了这段代码来测试它:

NSURL(string: "www.google.com") >>= { println("\($0)") }

它没有编译。这是Xcode的错误消息:

  

为运营商找到了不明确的运营商声明。运营商不是   已知的二元运算符

3 个答案:

答案 0 :(得分:9)

我可以确认你所看到的是真正发生的事情。我自己尝试了,我也看到了相同的结果。

我的观点是>>=在某种程度上与某些其他运算符(可能是咬合移位运算符:>>)冲突,或者在其他地方也被声明(你可以看到为什么我认为{{3} }})。我在框架中成功声明了自定义运算符,并在之前使用了主应用程序代码中的那些(例如,您可以看到here。)

我建议将自定义运算符重命名为其他内容。当我这样做(将自定义运算符重命名为>>>=)时,编译器停止了抱怨并且我的应用程序编译得很好。

稍后编辑

确定。所以这可能会有所帮助。基本上,当一个操作符已经被声明并且你想要为该操作符添加额外的功能时(例如像3 * "Hello"这样的事情,如here所说他想要的)你所需要的只是do 重载该运算符的方法。

基本上,在您的具体情况下,我现在是100%,>>=是已经声明的运算符,您可以继续在框架中添加这些行:

public func >>=<A, B>(a: A?, f: A -> B?) -> B? {
    if let a = a { return f(a) }
    else { return .None }
}

这将使您的操作员工作。 但是它将继承原始运算符的优先级和关联性,从而减少对它应该如何表现的控制。

答案 1 :(得分:8)

我明白了。我认为运算符(infix operator >>= {associativity left})的声明是特定于模块的。您无法对其应用访问控制。但是可以在其他模块中访问操作员功能。因此,为了完成这项工作,我必须复制操作员声明并将其粘贴到主项目中。

答案 2 :(得分:2)

仅添加

似乎就足够了
infix operator + : Additive

在每个要应用框架定义的运算符的源中,假设您的框架有一些

public func + (lhs: ...

声明。

无论如何,如果你使用一个框架就需要添加它,这是令人讨厌的,我希望看到一些方法可以采用一些全局方法,导入框架也可以自动提供运算符。

编辑摆弄几个小时后,问题就消失了。我还没弄清楚原因是什么。我的基本框架中有很多infix声明(出于历史原因)。一旦我摆脱它们,一切都恢复正常。所以现在我只有infix的新运营商,没关系。但显然重新声明了现有的(例如*+等)。斯威夫特似乎已经开始蠢蠢欲动。