为什么 Swift 不允许自定义前缀小于和后缀大于运算符?

问题描述 投票:0回答:1

明确指出是不允许的,但我找不到理由。有没有明确具体的说明原因?

swift operator-overloading
1个回答
1
投票

tl;dr: Swift 阻止定义某些运算符,因为否则它们会与现有语言功能发生冲突:

  1. 前缀
    &
    保留给
    inout
    参数
  2. Postfix
    !
    保留用于可选的解包
  3. Postfix
    ?
    保留用于可选链接
  4. 中缀
    ?
    保留给三元运算符
  5. 前缀
    <
    和后缀
    >
    保留用于定义通用参数列表
  6. =
    无条件保留分配
  7. 前缀
    ?
    和无条件
    ->
    是保留的,但在语言中并未实际使用

如果编写并编译

// Test.swift
prefix operator <

编译器会报错:

error: cannot declare a custom prefix '<' operator
prefix operator <
       ^

我们可以使用它来查找该消息在 Swift 编译器中的来源:从源代码中的

"cannot declare a custom"
搜索,您将在
DiagnosticsSema.def
中找到它,其中来自编译器语义验证阶段的诊断消息是已保存:

ERROR(redefining_builtin_operator,none,
      "cannot declare a custom %0 '%1' operator", (StringRef, StringRef))

如果您随后搜索

redefining_builtin_operator
以查找生成此诊断信息的位置,您将在
检查 
AttributeChecker::checkOperatorAttribute
 之后在 
isBuiltinOperator
中找到它。

isBuiltinOperator
本身给了我们上面的保留运算符列表:

/// Return true if this is a builtin operator that cannot be defined in user
/// code.
static bool isBuiltinOperator(StringRef name, DeclAttribute *attr) {
  return ((isa<PrefixAttr>(attr)  && name == "&") ||   // lvalue to inout
          (isa<PostfixAttr>(attr) && name == "!") ||   // optional unwrapping
          // FIXME: Not actually a builtin operator, but should probably
          // be allowed and accounted for in Sema?
          (isa<PrefixAttr>(attr)  && name == "?") ||
          (isa<PostfixAttr>(attr) && name == "?") ||   // optional chaining
          (isa<InfixAttr>(attr)   && name == "?") ||   // ternary operator
          (isa<PostfixAttr>(attr) && name == ">") ||   // generic argument list
          (isa<PrefixAttr>(attr)  && name == "<") ||   // generic argument list
                                     name == "="  ||   // Assignment
          // FIXME: Should probably be allowed in expression position?
                                     name == "->");
}
© www.soinside.com 2019 - 2024. All rights reserved.