字符串连接运算符 + 歧义

String Concatenation Operator + Ambiguity

我目前正在研究一种基于 JVM 的编程语言,该语言支持运算符重载和自定义运算符。我想坚持使用 Java 并使用 + 运算符进行字符串连接,这是在我的语言中实现并完美运行的。但是,该运算符也用于其他各种地方,例如将元素添加到集合中:

public interface Collection[E]
{
    // ...
    public Collection[E] +(E element)
    // ...
}

List[String] strings = List()
List[String] strings2 = strings + "a"

如您所见,这里有一个歧义:strings + "a" 可以表示 'call the + method of Collection to add an element to the strings' 或“将 strings 转换为字符串并将字符串 "a" 附加到那个字符串`。对于第二个意思,上面的代码会产生一个编译时类型错误,如果你用我的语言输入这段代码,目前会发生这种情况。

我将如何解决这个歧义,其他具有运算符重载和 + 字符串连接的语言(例如 Scala、Xtend 等)如何处理这个问题?

你可以从左到右评价; strings + "a"则处理如下:

  • strings 的定义中查找运算符 +,它接受 "a"
  • 类型的参数
  • 可选,使用交换的参数重试,否则失败

在线阅读有关表达式求值的内容:

Programming Languages: Principles and Paradigms, chapter 6.1.2/6.1.3

在我看来,处理歧义的正确方法是产生错误。你的语言不应该试图猜测用户的意思。

但这意味着您需要非常小心,不要在您的库中引入歧义。因此,我认为您不应该对字符串和列表连接使用相同的运算符。

如果您担心(您应该担心),请定义它。

Python 除了正常的正向运算符之外,还有一个反向运算符的概念。这些工作有一个定义的方法。

C++ 采用 "there's no such thing as a reverse-operator, but things can be casted." 的方法 根据 Python 的规则,您的示例将是:

Python 会这样做:

  • 'List[String]' 有 + 运算符吗?是
  • 调用它。
  • 它返回了 NotImplemented?该死的。 'String' 有反向运算符吗?
  • 如果是,请调用它。

C++ 会这样做:

  • 是否有任何通过标准转换序列或模板替换匹配参数的 operator+ 重载?是:List[String] 的 operator+(追加).

现在,如果不是这样,接下来它会这样做:

  • 是否有通过用户定义的转换序列匹配参数的 operator+ 重载?

如有必要,这将遍历所有可能的 operator+ 函数的列表,并查看参数是否可以进行基于构造函数或基于运算符的强制转换以使其适合函数或函数的模板实例化。这是它试图将 List[String] 转换为 String 的时候,但它可能会发现 List[String] 和 String 之间没有用户定义的转换。

故事的寓意:定义它。