• Swift更新至2.2版本 语言变化


    1.允许(大部分)关键字作为参数标签

    参数标签是swift函数的接口的一个重要组成部分,描述特定参数的函数,提高可读性。有时候,最自然的与语言关键字标签一个论点一致标签,例如,重复,或推迟。应该允许这样的关键词作为参数标签,允许更好的表达这些接口。

    动机是什么?

    在一些功能,标签为特定参数的最佳理由正好和语言关键字。例如,考虑一个module-scope函数,发现集合中的一个特定值的指数。自然语言是这样indexOf(_:in:):

    indexOf(value, in: collection)

    然而,因为在一个关键字,会需要使用引号的逃避,eg:
    indexOf(value, `in`: collection)
    在swift特定义新的api时,作者往往会选择其他non-keyword的话(如。within 例子中),即使他们并不理想.然而,这个问题也出现在导入objective - c api”省略不必要的词“启发式,要求摆脱使用这些api.例如:
    event.touchesMatching([.Began, .Moved], `in`: view)
    NSXPCInterface(`protocol`: SomeProtocolType.Protocol)


    提出解决方案:允许使用的关键词除了inout、var,le t 参数标签。这会影响三个地方的语法:
    1.调用表达式,比如上面的示例。在这里,我们没有这样的含糊不清,因为“:”不出现在任何语法在括号表达式列表。到目前为止,这是最重要的。
    2.函数/下标/初始值设定项声明:除了上面的三个除外,这里没有歧义,因为关键字永远是紧随其后的是一个标识符,“:”,或者“_”。例如:
    func touchesMatching(phase: NSTouchPhase, in view: NSView?) -> Set<NSTouch>


    介绍的关键字或修改一个参数——目前只是“inout”,“let”,“var”——将需要保留以前的含义。如果我们发明一个API,使用这样的关键词,他们仍然需要back-ticked:
    func addParameter(name: String, `inout`: Bool)
    3.功能类型:# 2,这是很简单的,因为参数名称总是后跟一个“:”:
    (NSTouchPhase, in: NSView?) -> Set<NSTouch>
    (String, inout: Bool) -> Void





    2.元组比较运算符
    == , != ,< , <= , > , >= 运算符进行比较
    @warn_unused_result
    public func == <A: Equatable, B: Equatable, C: Equatable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
      return lhs.0 == rhs.0 && lhs.1 == rhs.1 && lhs.2 == rhs.2
    }
    
    @warn_unused_result
    public func != <A: Equatable, B: Equatable, C: Equatable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
      return lhs.0 != rhs.0 || lhs.1 != rhs.1 || lhs.2 != rhs.2
    }
    
    @warn_unused_result
    public func < <A: Comparable, B: Comparable, C: Comparable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
      if lhs.0 != rhs.0 { return lhs.0 < rhs.0 }
      if lhs.1 != rhs.1 { return lhs.1 < rhs.1 }
      return lhs.2 < rhs.2
    }
    @warn_unused_result
    public func <= <A: Comparable, B: Comparable, C: Comparable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
      if lhs.0 != rhs.0 { return lhs.0 < rhs.0 }
      if lhs.1 != rhs.1 { return lhs.1 < rhs.1 }
      return lhs.2 <= rhs.2
    }
    @warn_unused_result
    public func > <A: Comparable, B: Comparable, C: Comparable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
      if lhs.0 != rhs.0 { return lhs.0 > rhs.0 }
      if lhs.1 != rhs.1 { return lhs.1 > rhs.1 }
      return lhs.2 > rhs.2
    }
    @warn_unused_result
    public func >= <A: Comparable, B: Comparable, C: Comparable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
      if lhs.0 != rhs.0 { return lhs.0 > rhs.0 }
      if lhs.1 != rhs.1 { return lhs.1 > rhs.1 }
      return lhs.2 >= rhs.2
    }





    3. 用associatedtype 替换 typealias 关键字相关的类型声明、
    介绍:
    目前typealias关键字用于声明两种类型:
    类型别名(替代名称为现有类型)
    相关类型(占位符名称类型作为协议的一部分)
    这两种声明是不同的,应该使用不同的关键字。这将强调它们之间的差异,减少周围的一些混乱的使用相关联的类型。拟议的新关键字是associatedtype。

    动机是什么?
    重用typealias相关类型声明是混乱在许多方面。它不明显,typealias协议意味着别的东西比在其他地方。初学者隐藏相关类型的存在,使他们误解了编写代码。目前还不清楚具体类型别名是禁止内部协议。特别是,2 + 3导致程序员编写

    protocol Prot {
        typealias Container : SequenceType
        typealias Element = Container.Generator.Element
    }

    没有意识到Element是一个新类型 用Container.Generator.Element的默认值去替换类型别名Container.Generator.Element。

    然问 这样的代码
    protocol Prot {
        typealias Container : SequenceType
    }
    extension Prot {
        typealias Element = Container.Generator.Element
    }

    作为一个类型别名Container.Generator.Element声明Element。这些微妙的目前需要仔细考虑理解的语言。
    解决方案 :
    对于声明相关的类型,用associatedtype替换typealias关键字。这可以解决上面提到的问题:typealias现在可以只用于声明类型别名。初学者现在被迫学习相关类型在创建协议。现在可以显示一个错误消息,当有人试图创建一个类型别名在一个协议。这消除了困惑显示在前面的代码片段。
    protocol Prot {
        associatedtype Container : SequenceType
        typealias Element = Container.Generator.Element // error: cannot declare type alias inside protocol, use protocol extension instead   不能声明类型别名内部协议,  使用协议扩展
    }
    
    
    protocol Prot {
        associatedtype Container : SequenceType
    }
    extension Prot {
        typealias Element = Container.Generator.Element
    }
    选择关键词是:typeassociatedrequiredtypeplaceholdertype, …
    声明相关的类型,我建议添加associatedtype和轻视typealias在swift2.2中,和完全删除typealias 在swift3。作为另一个只是替换一个关键字,过渡到associatedtype可以轻易被自动化的风险没有任何破坏现有代码。




    4.命名函数作为参数标签

    介绍:
    swift包括支持一级函数,这样任何函数(或方法)可以放在一个函数类型的值。然而,当指定一个函数的名称,我们只能提供基本名称,(如insertSubview)没有标签的论证。对于重载函数,这意味着人们必须消除
    类型信息的基础上歧义,这是尴尬的和冗长的。这个提议允许一个提供参数标签当引用一个函数,消除了在大多数情况下需要提供类型的上下文。
    Swift-evolution线程:这个提议是这里讨论的初稿。它包括支持命名getter / setter(分别由迈克尔·亨森在这里继续)。乔Groff让我相信,眼镜是一种更好的方法来处理getter / setter,所以我把他们从这个版本的建议。
    动机是什么?
    extension UIView {
      func insertSubview(view: UIView, at index: Int)
      func insertSubview(view: UIView, aboveSubview siblingSubview: UIView)
      func insertSubview(view: UIView, belowSubview siblingSubview: UIView)
    }

    调用这些方法
    someView.insertSubview(view, at: 3)
    someView.insertSubview(view, aboveSubview: otherView)
    someView.insertSubview(view, belowSubview: otherView)
    然而,当引用函数创建一个函数值,一个不能提供标签:
    let fn = someView.insertSubview // ambiguous: could be any of the three methods
    这个是模棱两可的:可以是任何的三个方法

    可以使用消除歧义的类型注解:

    let fn: (UIView, Int) = someView.insertSubview // ok: uses insertSubview(_:at:)
    let fn: (UIView, UIView) = someView.insertSubview // error: still ambiguous!  仍然模棱两可

    解决后者的情况下,一个人必须回到创建一个闭包:
    let fn: (UIView, UIView) = { view, otherView in
      button.insertSubview(view, aboveSubview: otherView)
    }

    这是痛苦的乏味。一个额外的动机:swift应该得到一些要求objective - c的方法选择器对于一个给定的方法(而不是写一个字符串)。这样的一个操作的参数可能会引用一个方法,将受益于任何方法能够名称,包括getter和setter。

    解决方法:
    我建议延长函数命名允许化合物swift名称(如。,insertSubview(_:aboveSubview:))可能发生的任何一个名字。具体地说,
    let fn = someView.insertSubview(_:at:)
    let fn1 = someView.insertSubview(_:aboveSubview:)

    具体来说,相同的语法也可以指的是初始化,例如,
    let buttonFactory = UIButton.init(type:)
    “产生给定方法的objective - c选择器”操作将一个单独的建议的主题。然而,这是一种可能性,插图如何利用提出的语法:
    let getter = Selector(NSDictionary.insertSubview(_:aboveSubview:)) // produces insertSubview:aboveSubview:.

    无参数的函数引用仍需要通过上下文类型信息消歧
    func foo(x: Int, y: Int = 7, strings: String...) { ... } let fn1 = foo(x:y:strings:) // okay let fn2 = foo(x:) // error: no function named 'foo(x:)'
    当所有参数_,这提供了任何方法名称的能力
    aGameView.insertSubview(_, aboveSubview: _)
    或者
    { aGameView.insertSubview($0, aboveSubview: playingSurfaceView) }


    5.引用oc 选择器的方法
    #selector 关键字 引入oc 的方法
    let sel = #selector(((UIView.insertSubview(_:at:)) as (UIView) -> (UIView, Int) -> Void))
    as可用于中同名迅速消除歧义的方法


    6.限制
    AnySequence.init 任何序列
    为了让AnySequence委托调用底层的序列,其初始化应该有额外的约束。
     






  • 相关阅读:
    Codeforces 1093D(染色+组合数学)
    Codeforces 1093C (思维+贪心)
    Codeforces 1082D (贪心)
    Codeforces 433A (背包)
    BZOJ 3262(Treap+树状数组)
    BZOJ 1588 (treap)
    Codeforces 1061C (DP+滚动数组)
    Codeforces 1080C 题解(思维+二维前缀和)
    周记 2015.07.12
    周记 2015.07.04
  • 原文地址:https://www.cnblogs.com/PengFei-N/p/5308299.html
Copyright © 2020-2023  润新知