问题 什么是Swift中使用的〜>(代码大于)运算符?


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

infix operator ~> {
    associativity left
    precedence 255
}

这在Swift中用于什么?它似乎已声明,但没有定义利用它的函数。其他开发人员已将它用于反应模式和队列之间的封堵,但我想知道为什么它在标准框架中定义。我推测它是为了保留开发人员使用的自定义运算符,因为它具有最高的优先级。


8157
2017-11-05 13:22


起源

由于它是最高优先级,因此它将与对象/可选引用相关联。 - Sulthan
我不确定你能做出这样的假设。没有为“。”,“!”或“?”声明的后缀运算符我不确定你能宣布他们。这些是语言本身的一部分,并作为其他函数调用的语法糖。 - Jason


答案:


由于Swift是开源的,我们可以看到包含它的实际原因 ~> 在stdlib中: 作为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 }

可以在中找到详细的示例 测试/原型/ GenericDispatch.swift

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


怎么样 ~> 作品

在Swift 2中,唯一剩下的实例 ~> 是个 abs 功能(也可能会消失)。我们可以看到实际情况 ~> 作品。从 STDLIB /公/核心/ IntegerArithmetic.swift.gybSignedInteger 协议定义了一个 ~> 运营商:

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)

然后我们提供 默认实现 的 _Abs 当给出一个 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

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

最后我们隐藏了 ~> 调用公共包装器方法。如果 T 实际上是一个 AbsoluteValuable,更专业,更高效 ~> 将被选中。

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


你不需要 ~>

这种模式也可以完成  调用 ~> 运算符,使用协议扩展:

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中消失了:使用这种技术的所有专业化都已经改为使用更明显的协议扩展,例如:


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


5
2017-07-14 15:39





看起来,它是相关的集合/序列/索引类型

根据 定义 - 斯威夫特

protocol SequenceType : _Sequence_Type {
  typealias Generator : GeneratorType
  func generate() -> Generator
  func ~>(_: Self, _: (_UnderestimateCount, ())) -> Int
  func ~><R>(_: Self, _: (_PreprocessingPass, ((Self) -> R))) -> R?
  func ~>(_: Self, _: (_CopyToNativeArrayBuffer, ())) -> _ContiguousArrayBuffer<Self.Generator.Element>
}

protocol CollectionType : _CollectionType, SequenceType {
  subscript (position: Self.Index) -> Self.Generator.Element { get }
  func ~>(_: Self, _: (_CountElements, ())) -> Self.Index.Distance
}

protocol ForwardIndexType : _ForwardIndexType {
  func ~>(start: Self, _: (_Distance, Self)) -> Self.Distance
  func ~>(start: Self, _: (_Advance, Self.Distance)) -> Self
  func ~>(start: Self, _: (_Advance, (Self.Distance, Self))) -> Self
}

protocol SignedNumberType : _SignedNumberType {
  prefix func -(x: Self) -> Self
  func ~>(_: Self, _: (_Abs, ())) -> Self
}

func ~><T : _CollectionType>(x: T, _: (_CountElements, ())) -> T.Index.Distance
func ~><T : _CollectionType>(x: T, _: (_UnderestimateCount, ())) -> Int
func ~><T : _CollectionType, R>(s: T, args: (_PreprocessingPass, ((T) -> R))) -> R?
func ~><T : _SequenceType>(s: T, _: (_UnderestimateCount, ())) -> Int
func ~><T : _SequenceType, R>(s: T, _: (_PreprocessingPass, ((T) -> R))) -> R?
func ~><S : _Sequence_Type>(source: S, _: (_CopyToNativeArrayBuffer, ())) -> _ContiguousArrayBuffer<S.Generator.Element>
func ~><C : CollectionType where C._Element == C._Element>(source: C, _: (_CopyToNativeArrayBuffer, ())) -> _ContiguousArrayBuffer<C._Element>
func ~><T>(x: EmptyCollection<T>, _: (_CountElements, ())) -> Int
func ~><T : _ForwardIndexType>(start: T, rest: (_Distance, T)) -> T.Distance
func ~><T : _ForwardIndexType>(start: T, rest: (_Advance, T.Distance)) -> T
func ~><T : _ForwardIndexType>(start: T, rest: (_Advance, (T.Distance, T))) -> T
func ~><T : _BidirectionalIndexType>(start: T, rest: (_Advance, T.Distance)) -> T
func ~><T : _BidirectionalIndexType>(start: T, rest: (_Advance, (T.Distance, T))) -> T
func ~><T : _RandomAccessIndexType>(start: T, rest: (_Distance, (T))) -> T.Distance
func ~><T : _RandomAccessIndexType>(start: T, rest: (_Advance, (T.Distance))) -> T
func ~><T : _RandomAccessIndexType>(start: T, rest: (_Advance, (T.Distance, T))) -> T
func ~><T : _SignedNumberType>(x: T, _: (_Abs, ())) -> T
func ~><T : AbsoluteValuable>(x: T, _: (_Abs, ())) -> T
func ~><T>(x: CollectionOfOne<T>, _: (_CountElements, ())) -> Int

例如,

42 ~> _advance(12) // -> 54
42 ~> _distanceTo(23) // -> -19

我不知道如何使用这些: - /


7
2017-11-05 14:30





SwiftDoc 此运算符已从运算符章节中删除 Swift 3.0


0
2017-10-10 10:13