如何在Scala中取消导入字符串“+”运算符?

8 浏览
0 Comments

如何在Scala中取消导入字符串“+”运算符?

我正在编写一种DSL,其中“+”操作符严格是数字类型的,就像其他一些流行的编程语言一样。它接近完成,但是String类的“+”操作符正在破坏我的隐式转换。有没有什么语法可以取消导入String类的操作符?

为了更清楚,我想要的结果是:

scala> var x = "2" + 3;

x: java.lang.String = 23

我希望得到的结果是:x: Int = 5

我想我只需要两个步骤来实现这个目标:

  • 删除(在我的范围内取消导入)String类的“+”定义
  • 定义String到Int的隐式转换

我在第一步卡住了。

谢谢

0
0 Comments

Scala中String的"+"运算符是String类的一个方法,因此它无法被取消导入。

要理解这个问题的原因,我们需要先了解Scala中的import和unimport的概念。在Scala中,import语句用于导入其他类或对象中的成员,使得在当前作用域中可以直接访问这些成员。相反,unimport语句用于取消导入,即在当前作用域中取消对某个类或对象的成员的访问权限。

然而,对于String的"+"运算符,它是String类的一个方法,而不是一个独立的成员。因此,无法通过unimport语句来取消对它的导入。

那么,如果我们确实想要取消导入String的"+"运算符,有没有其他的解决方法呢?答案是有的。

一种解决方法是使用更具体的import语句来覆盖默认的导入。比如,我们可以使用如下的import语句来导入其他类库中的"+"运算符,从而覆盖默认的String类中的"+"运算符:

import otherlibrary.StringExtensions._

这样,我们就可以使用otherlibrary中的StringExtensions类中的"+"运算符,而不是默认的String类中的"+"运算符。

另一种解决方法是使用隐式转换。通过定义一个隐式转换函数,我们可以将String对象转换为其他类型的对象,从而避免使用String类中的"+"运算符。例如,我们可以定义一个将String对象转换为StringBuilder对象的隐式转换函数:

implicit def stringToBuilder(s: String): StringBuilder = new StringBuilder(s)

然后,在使用"+"运算符时,Scala会自动调用这个隐式转换函数将String对象转换为StringBuilder对象。这样,我们就可以使用StringBuilder类中的"+"运算符,而不是String类中的"+"运算符。

虽然无法直接取消导入String类中的"+"运算符,但我们可以通过使用更具体的import语句或者定义隐式转换函数来达到类似的效果。这些方法可以帮助我们在Scala中更灵活地使用"+"运算符。

0
0 Comments

问题:如何在Scala中取消导入String的"+"运算符?

在Scala中,String类型的"+"运算符用于连接两个字符串。然而,有时候我们可能希望取消导入该运算符,以避免产生歧义或者与其他操作冲突。下面介绍了问题的原因以及解决方法。

问题的原因:

Scala中的"+"运算符被用于连接字符串,但有时我们可能希望取消这个运算符的导入。取消导入的原因可能包括以下几点:

1. 避免与其他操作符(例如数学运算符)发生冲突。

2. 避免在使用"+"运算符时产生歧义。

解决方法:

在Scala中,无法直接取消导入String类型的"+"运算符。但是,我们可以使用其他方式来避免使用该运算符。以下是一种解决方法:

1. 使用+:运算符:使用+:运算符可以代替"+"运算符,它可以将字符串连接到另一个字符串的前面。例如,可以使用以下代码实现字符串连接:"2" +: "3"。

2. 使用toInt方法:另一种解决方法是使用toInt方法将字符串转换为整数,然后使用数学运算符进行计算。例如,可以使用以下代码实现字符串连接:"2".toInt + 3。

通过使用上述方法,我们可以避免直接使用String类型的"+"运算符,从而解决了取消导入该运算符的问题。

0
0 Comments

在Scala规范的第12.3.1节中,String的"+"方法在编译器中有特殊处理。虽然不确定,但我认为这意味着无法"取消导入"该方法,这很遗憾,因为它真正破坏了类型系统(就像相关的toString方法一样)。

你能在DSL中使用不同的操作符名称吗,例如"++"或"&"?

"+"方法受编译器特殊处理与其是否可以导入或取消导入无关。该语言应该非常正交,无论方法是由编译器合成还是由运行时库提供,都应该在语义上以相同方式对待所有类方法。

如果确实在String类上明确指定了"+"方法,我会同意你的观点,但规范只是暗示了这一点,并且我认为可以将其解释为存在一种隐式转换(嵌入到编译器中,因此无法"取消导入")到某种类型(例如StringAdd),使客户端可以将String视为定义有"+"方法的类型。我很乐意被证明是错的,但即使通过对String(和RichString)进行运行时反射,我也找不到"+"(即$plus)方法。

谢谢,听起来又是一种"编译器魔法",实际上破坏了正交性,并与其他语言特性和库产生了意想不到的交互。

是的,我不确定为什么它不能以与Predef.any2stringadd相同的方式实现,例如Predef.string2stringadd:String => StringAdd。

在现代Scala中,可以取消导入String并使用自定义插值器生成自定义类型。目前不可能的是为字符串字面量语法提供自定义的"empty"插值器。

0