Dotty项目中的操作符规则详解
dotty The Scala 3 compiler, also known as Dotty. 项目地址: https://gitcode.com/gh_mirrors/do/dotty
前言
在Scala 3(Dotty)中,操作符的使用规则发生了一些重要变化,这些变化旨在提高代码的一致性和可读性。本文将深入解析这些新规则,帮助开发者更好地适应Scala 3的操作符使用方式。
中缀操作符的infix
修饰符
基本概念
在Scala 3中,字母数字方法(alphanumeric method)若要作为中缀操作符使用,必须在定义时添加infix
修饰符。这是与Scala 2的一个重要区别。
trait MultiSet[T]:
infix def union(other: MultiSet[T]): MultiSet[T] // 可以使用中缀语法
def difference(other: MultiSet[T]): MultiSet[T] // 不能使用中缀语法
使用场景
- 字母数字方法:由字母、数字、
$
和_
组成的标识符,或满足java.lang.Character.isIdentifierPart(c)
的Unicode字符 - 符号操作符:如
+
、-
、*
等,无需infix
修饰符,默认支持中缀语法
迁移注意事项
为了平滑迁移到Scala 3,字母数字操作符的警告将从Scala 3.1开始生效,或在使用-source future
选项时立即生效。
@targetName
注解的最佳实践
为什么需要@targetName
符号操作符虽然简洁,但在以下场景可能带来问题:
- 与其他语言交互时难以识别
- 堆栈跟踪中可读性差
- 难以通过搜索找到定义
使用方法
import scala.annotation.targetName
trait MultiSet[T]:
@targetName("intersection")
def *(other: MultiSet[T]): MultiSet[T]
这样,*
操作符就有了一个明确的别名"intersection",提高了代码的可维护性。
类型的中缀表示
Scala 3扩展了infix
修饰符的用途,允许在类型定义中使用:
infix type or[X, Y]
val x: String or Int = ... // 中缀类型语法
这种语法特别适合表示类型级别的组合操作。
多行表达式中的操作符
Scala 3改进了多行表达式的解析规则,允许操作符出现在行首:
val str = "hello"
++ " world" // 操作符在行首
++ "!"
解析规则细节
编译器不会在以下情况推断分号:
- 行首是符号标识符或反引号标识符
- 不是空行后的第一行
- 操作符后至少有一个空格和表达式起始标记
- 如果操作符独占一行,下一行的缩进必须≥操作符行的缩进
示例对比
// 合法中缀操作
freezing
| boiling
// 两个独立语句
freezing
!boiling
一元操作符的特殊规则
一元操作符(unary_+
、unary_-
、unary_!
、unary_~
)必须:
- 不能有显式的参数列表(即使是空的)
- 必须严格遵循命名规范
class C:
def unary_! : Int = ... // 正确
def unary_!(): Int = ... // 错误,不能有参数列表
总结
Scala 3对操作符的规则进行了多项改进,主要变化包括:
- 引入
infix
修饰符明确中缀操作意图 - 推荐使用
@targetName
提高符号操作符的可维护性 - 改进多行表达式的操作符解析
- 明确一元操作符的限制
这些变化虽然增加了些许约束,但显著提高了代码的一致性和可读性,是Scala语言演进中的重要改进。
dotty The Scala 3 compiler, also known as Dotty. 项目地址: https://gitcode.com/gh_mirrors/do/dotty
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考