我目前正在研究一种基于JVM的编程语言,它支持运算符重载和自定义运算符。我想坚持使用Java并使用+
运算符进行字符串连接,这是在我的语言中实现并完美运行的。但是,运算符也可用于其他各种位置,例如向集合中添加元素:
public interface Collection[E]
{
// ...
public Collection[E] +(E element)
// ...
}
List[String] strings = List()
List[String] strings2 = strings + "a"
正如您所看到的,此处存在歧义:strings + "a"
可能意味着调用+
的{{1}}方法向Collection
添加元素}'或者'将strings
转换为字符串并附加字符串" a"到那个String`。对于第二个含义,上面的代码会生成一个编译时类型错误,如果你用我的语言输入这个代码,那么这个错误就是当前的情况。
我将如何解决这种歧义,以及其他语言如何使用运算符重载和strings
进行字符串连接(例如Scala,Xtend,...)处理此问题?
答案 0 :(得分:1)
如果你担心(你应该这样),那就定义它。
除了普通的前向运算符之外,Python还有一个反向运算符的概念。这些工作有一种定义的方法。
C ++采用"不存在反向运算符的方法,但事情可以被投入。"根据Python的规则,你的例子是:
Python会这样做:
C ++会这样做:
现在,如果不是这样,那么接下来会这样做:
如果需要,这将遍历所有可能的operator +函数的列表,并查看参数是否可以进行基于构造函数或基于运算符的转换以使它们适合函数或函数的模板实例化。这是它何时尝试将List [String]强制转换为String,但它可能会发现List [String]和String之间没有用户定义的转换。
故事的寓意:定义它。
答案 1 :(得分:0)
你可以从左到右评估; strings + "a"
然后按如下方式处理:
+
的定义中查找运算符strings
,该"a"
接受for
了解在线表达评估:
Programming Languages: Principles and Paradigms, chapter 6.1.2/6.1.3
答案 2 :(得分:0)
在我看来,处理歧义的正确方法是产生错误。您的语言不应该试图猜测用户的意思。
但这意味着您需要非常小心不要在库中引入歧义。因此,我认为你不应该对字符串和列表连接使用相同的运算符。