什么是~>(波浪号大于)运算符用于 Swift 中? [英] What is the ~> (tilde greater than) operator used for in Swift?

查看:31
本文介绍了什么是~>(波浪号大于)运算符用于 Swift 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Swift 1.1 包含 ~> 运算符的声明:

Swift 1.1 includes the declaration of the ~> operator:

infix operator ~> {
    associativity left
    precedence 255
}

这在 Swift 中有什么用?它似乎已声明,但没有定义利用它的函数.其他开发人员已将它用于响应式模式和队列之间的封送处理,但我想知道为什么在标准框架中定义它.我猜测它是为了保留"一个自定义运算符供开发人员使用,因为它具有尽可能高的优先级.

What is this used for in Swift? It appears to be declared but no functions are defined that leverage it. Other developers have used it for reactive patterns and for marshaling closures between queues, but I am wondering why it's defined in the standard framework. I surmise that it's there to "reserve" a custom operator for developer use, given that it has the highest precedence possible.

推荐答案

由于 Swift 已经开源,我们可以看到在 stdlib 中包含 ~> 的实际原因:作为 Swift 中方法专业化的子协议的解决方法1.x.

Since Swift has been open-sourced we can see the actual reason for including the ~> in stdlib: as a workaround for method specialization in a child protocol in Swift 1.x.

// Workaround for <rdar://problem/14011860> SubTLF: Default
// implementations in protocols.  Library authors should ensure
// that this operator never needs to be seen by end-users.  See
// test/Prototypes/GenericDispatch.swift for a fully documented
// example of how this operator is used, and how its use can be hidden
// from users.
infix operator ~> { associativity left precedence 255 }

可以在 test/Prototypes/中找到详细示例GenericDispatch.swift.

注意:不要在 Swift 2+ 中使用 ~>.这是一个历史性的解决方法.不再需要它了.继续阅读.

Note: Do not use ~> in Swift 2+. This is a historical workaround. It is no longer needed. Read on.

在 Swift 2 中,~> 唯一剩下的实例是 abs 函数(它可能也会消失).我们可以看到 ~> 实际上是如何工作的.来自 stdlib/public/core/IntegerArithmetic.gybSignedInteger 协议定义了一个 ~> 操作符:

In Swift 2, the only remaining instance of ~> is the abs function (which is probably going away as well). We can see how actually ~> works. From stdlib/public/core/IntegerArithmetic.swift.gyb, the SignedInteger protocol defines an ~> operator:

struct _Abs {}

protocol SignedNumber: Comparable {
    prefix func -(_: Self) -> Self

    func ~> (_: Self, _: (_Abs, ()) -> Self
}

func ~> <T: SignedNumber>(x: T, _: (_Abs, ()) -> T {
    return x < 0 ? -x : x
}

这里,箭头的 RHS ~> 指定可以向对象发送什么命令.把 p~>(cmd, args) 想象成类似于 p.cmd(args) 的东西.

Here, the RHS of the arrow ~> specifies what command can be sent to the object. Think of p~>(cmd, args) as something like p.cmd(args).

然后,当给定 SignedNumber 时,我们提供 _Abs默认实现.

Then we provide the default implementation of _Abs when given a SignedNumber.

protocol AbsoluteValuable : SignedNumber {
    static func abs(_: Self) -> Self
}

func ~> <T: AbsoluteValuable>(x: T, _: (_Abs, ())) -> T {
    return T.abs(x)
}

接下来,我们有一个子协议,AbsoluteValuable,它可能有比 x < 更有效的方法来计算绝对值.0 ?-x : x.然后我们专门为 AbsoluteValuable 使用 ~> 运算符.

Next, we have a child protocol, AbsoluteValuable, which perhaps has a more efficient way to compute the absolute value than x < 0 ? -x : x. We then specialize the ~> operator for AbsoluteValuable.

func abs<T: SignedNumber>(_ x: T) -> T {
    return x ~> (_Abs(), ())
}

最后,我们将 ~> 调用隐藏在公共包装方法中.如果 T 实际上是一个 AbsoluteValuable,则将选择更专业、因此更高效的 ~>.

Finally we hide the ~> call in a public wrapper method. If T is actually an AbsoluteValuable, the more specialized and thus more efficient ~> will be chosen.

这也是为什么我们得到 42 ~>_advance(12)42 ~>_distanceTo(23)@rintaro的回答所示,因为.advanceBy.distanceTo 方法对于一般的 ForwardIndexType 是 O(n),但如果类型是 RandomAccessIndexType,则可以在 O(1) 中实现.

This is also why we get 42 ~> _advance(12) or 42 ~> _distanceTo(23) as shown in @rintaro's answer, because the .advanceBy and .distanceTo methods are O(n) for a general ForwardIndexType, but can be implemented in O(1) if the type is RandomAccessIndexType.

这种模式也可以在不调用 ~> 操作符的情况下完成,使用协议的扩展:

This pattern could also be done without invoking the ~> operator, using extensions on a protocol:

protocol SignedInteger: Comparable {
    prefix func -(_: Self) -> Self

    func genericAbs() -> Self
}

extension SignedInteger {
    func genericAbs() -> Self {
        return self < 0 ? -self : self
    }
}

protocol AbsoluteValueable: SignedInteger {
    static func abs(_: Self) -> Self
}

extension AbsoluteValueable {
    func genericAbs() -> Self {
        return Self.abs(self)
    }
    // normally you would allow subtypes to override
    // genericAbs() directly, instead of overriding 
    // static abs().
}

func abs<T: SignedInteger>(x: T) -> T {
    return x.genericAbs()
}

特别是这就是为什么除了 abs 之外的所有其他 ~> 实现都在 Swift 2 中消失了:所有使用这种技术的特化都已更改为使用协议扩展更明显,例如

In particular this is why all other ~> implementations besides abs are gone in Swift 2: all specializations using this technique has been changed to use protocol extensions which is more obvious, e.g.

注意:雷达问题 14011860 未公开,但我们可能会通过 OpenRadar 上的重复项看到该错误的范围:

Note: The radar problem 14011860 is not public, but we may see the scope of the bug by its duplicates on OpenRadar:

这篇关于什么是~&gt;(波浪号大于)运算符用于 Swift 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆