如何编写 Swift 中缀函数?

How do I write Swift infix functions?

我已经看到这样做了,但我就是无法理解它。不知何故,看起来很神奇,一些中缀函数工作正常,但其他函数根本无法编译。例如:

正如您在这里看到的,我的 then 函数作为传统函数工作,但不是中缀函数,但我的 * 函数有相反的问题。 有什么神奇的方法可以让我的 then 函数成为中缀函数?

附带问题:为什么我的 * 函数不能像传统函数一样工作?


代码供 text-only 读者和 copy-pasting:

public func * (let left:String, let right:Int) -> String {
    if right <= 0 {
        return ""
    }

    var result = left
    for _ in 1..<right {
        result += left
    }

    return result
}
*("Left", 6) // error: '*' is not a prefix unary operator
"Left" * 6   // "LeftLeftLeftLeftLeftLeft"

public func then (let left:String, let _ right:String) -> String {
    return left + right
}
then("Left", "Right") // "LeftRight"
"Left" then "Right"   // 2 errors: Consecutive statements on a line must be separated by ';'

Swift 标准库已经将 * 定义为中缀运算符:

infix operator * {
    associativity left
    precedence 150
}

您将在 Swift Standard Library Operators Reference。或者,在 Xcode 中的 import Swift 语句中 "command-click" 并搜索 "operator".

要在 "traditional" 函数调用中使用运算符,您必须将其括在括号中:

(*)("Left", 6)

如果你想定义你自己的中缀运算符,你必须添加一个 infix operator 声明。但是请注意,只有一组受限制的 字符对运算符有效(请参阅 Language Reference->Lexical Structure->Operators 了解精确规则)。特别是,运营商 名称必须(正如@dfri 已经说过的那样)以 /、=、-、+、!、*、%、<、>、&、|、^、?、~ 或其他 "symbol" 个字符。特别是,"then" 不是有效的运算符名称。

* 已经在 Swift:

中本机定义为二元中缀运算符
infix operator * {
    associativity left
    precedence 150
}

因此,func * (... 形式的任何函数都将重载此二元中缀运算符。另一方面,如果您尝试将 * 运算符用作 前缀一元 运算符,您将得到描述性错误 "* 不是前缀一元运算符,因为 * 本身并不作为前缀运算符存在。

您当然可以定义自己的 prefix 运算符 *:

prefix operator * { }
prefix func * (rhs: Int) -> Int {
    return rhs*rhs
}

var a : Int = 2
var b : Int = *a // 4

总结一下:一些运算符本机存在于 Swift 中,既作为前缀运算符又作为中缀运算符,例如-

/* Declared natively in Swift */
infix operator - {
    associativity left
    precedence 140
}

prefix operator - {
}

/* Example usage */
let a : Int = 2 - 1 // 1,  '-' infix operator used
let b : Int = -1    // -1, '-' prefix operator used

而其他的,例如 *,只是(本机地)用作中缀运算符。

另请注意,如果您想定义自己的自定义中缀运算符,其允许的名称有如下限制:

Custom operators can begin with one of the ASCII characters /, =, -, +, !, *, %, <, >, &, |, ^, ?, or ~, or one of the Unicode characters defined in the grammar below (which include characters from the Mathematical Operators, Miscellaneous Symbols, and Dingbats Unicode blocks, among others). After the first character, combining Unicode characters are also allowed.

来自 Language Reference - Lexical Structure.