Swift5新特性 & XCode 10.2更新


swift语法更新

  1. SE-0200 原始字符串
    添加了创建原始字符串的功能,其中\""被解释为这些文字符号本身,而不是转义字符或字符串终止符。这使得许多功能更加容易实现,比如正则表达式。
    要使用原始字符串,请在字符串前放置一个或多个#号,如下所示:
//正则表达式 regex1 == regex2
    let regex1 = "\\\\[A-Z]+[A-Za-z]+\\.[a-z]+"
    let regex2 = #"\\[A-Z]+[A-Za-z]+\.[a-z]+"#
    
 let keypaths = #"Swift 中的 keypaths 格式像这样: \Person.name ."#
 
 //原始字符串中包含#
 let anotherString = ##"这是一个包含“#”的原始字符串"##
 //多行字符串的原始字符串
 let multiline = #"""
    这是一个多行字符串:,
    “我才是
    多行字符串”。
    """#
 
 //原始字符串中插值
  let answer = 42
    let dontpanic = #"宇宙的终极答案是:\#(answer)."#
    

请注意,我如何使用\(answer)来使用字符串插值\(answer)将被解释为字符串中的字符,因此当您希望在原始字符串中进行字符串插值时,必须添加额外的`#'

2.SE-0235 在标准库中引入“Result”类型,使我们能够更简单、更清晰地处理复杂代码(如异步API)中的错误。
swift的“Result”类型实现为具有两种情况的枚举:“success”和“failure”。两者都是使用泛型实现的,这样它们就可以有一个相关值,但是“failure”必须是符合swift的“Error”类型。(如果你之前使用过这个库Result,你会发现他们几乎一模一样)

3.SE-0228字符串插值系统的升级:新增了用于调试struct的输出方法,如果你需要自定义某结构体的输出你需要扩展String.StringInterpolation并实现appendInterpolation()方法

struct User {
    var name: String
    var age: Int
}
extension String.StringInterpolation {
    mutating func appendInterpolation(_ value: User) {
        appendInterpolation("My name is \(value.name) and I'm \(value.age)")
    }
}

let user = User(name: "Guybrush Threepwood", age: 33)
 print("User details: \(user)")
 //输出:User details: My name is Guybrush Threepwood and I'm 33
 
 //格式化插值到字符串
extension String.StringInterpolation {
    mutating func appendInterpolation(_ number: Int, style: NumberFormatter.Style) {
        let formatter = NumberFormatter()
        formatter.numberStyle = style

        if let result = formatter.string(from: number as NSNumber) {
            appendLiteral(result)
        }
    }
}

 let number = Int.random(in: 0...100)
  let lucky = "The lucky number this week is \(number, style: .spellOut)."
 print(lucky)
 //输出:The lucky number this week is sixty-three.

在此基础上用户可以扩展更多类型的差之方法如:输出小数位数,控制电话号码格式,邮件格式等等,更多例子可以查看下方whats-new-in-swift-5-0

注意:旧_ExpressibleByStringInterpolation协议已被删除; 任何使用此协议的代码都需要针对新设计​​进行更新。一个#if compiler块可用于条件化4.2和5.0之间的代码,例如:

#if compiler(<5.0)
extension MyType : _ExpressibleByStringInterpolation { ... }
#else
extension MyType : ExpressibleByStringInterpolation { ... }
#endif

4.SE-0216新增语法糖 @dynamicCallable@dynamicallable是swift 4.2的@dynamicmemberlookup的扩展,其作用相同:使swift代码更容易与动态语言(如python和javascript)一起工作。

5.SE-0192新增 @unknown 关键字,此关键词可以用在switch语句中,Swift它要求所有switch语句覆盖所有情况,但有时我们需要忽略一些枚举值,我们使用default去处理忽略的情况,但当我们新增一个枚举类型,我们的switch语句没有更改,他也不再会提示错误,因为default以及处理了新的情况,为了更好地提示开发者使用@unknown default和原default具有相同的功能,并且编译器回升弄成一个警告⚠️提醒用户没有处理所有情况:

enum PasswordError: Error {
        case short
        case obvious
        case simple
    }
    //这个方法没有任何提示
    func showOld(error: PasswordError) {
        switch error {
        case .short:
            print("Your password was too short.")
        case .obvious:
            print("Your password was too obvious.")
        default:
            print("Your password was too simple.")
        }
    }
    
    func showNew(error: PasswordError) {
        switch error { //此行警告⚠️Switch must be exhaustive
        case .short:
            print("Your password was too short.")
        case .obvious:
            print("Your password was too obvious.")
        @unknown default:
            print("Your password wasn't suitable.")
        }
    }

6.SE-0230修改try的嵌套方式

struct User {
    var id: Int
    init?(id: Int) {
        if id < 1 {
            return nil
        }
        self.id = id
    }
    func getMessages() throws -> String {
        // complicated code here
        return "No messages"
    }
}

let user = User(id: 1)
let messages = try? user?.getMessages()

在swift4.2中上方代码中messages的类型将会是一个String??类型,在swift5中你会得到一个String?类型,这意味着,链式调用不会再使可选值发生嵌套。

7.SE-0225整数类型新增函数isMultiple(of:)判断是否是一个数的倍数

    let rowNumber = 4
    if rowNumber.isMultiple(of: 2) {
        print("Even")
    } else {
        print("Odd")
    }

8.SE-0218字典类型新增方法compactMapValues(),用于转换字典value的类型(空值将被移除)

 let times = [
        "Hudson": "38",
        "Clarke": "42",
        "Robinson": "35",
        "Hartis": "DNF"
    ]
    //将[String:String]转换成[String:Int]
 let finishers1 = times.compactMapValues { Int($0) }
  let finishers2 = times.compactMapValues(Int.init)
  // ["Hudson": 38, "Clarke": 42, "Robinson": 35]

9.SE-0213通过字面量强制初始化,
如果T符合其中一个ExpressibleBy*协议并且literal是一个文字表达式,那么T(literal)将使用一个和T的类型相同的构造方法,而不是使用T的默认构造函数

struct Q: ExpressibleByStringLiteral {
  typealias StringLiteralType =  String
  var question: String

  init?(_ possibleQuestion: StringLiteralType) {
    return nil
  }
  init(stringLiteral str: StringLiteralType) {
    self.question = str
  }
}

_ = Q("ultimate question")    // 'nil'
_ = "ultimate question" as Q  // Q(question: 'ultimate question')

10.SR-5719在Swift 5模式下,@autoclosure参数不能再转发到另一个函数调用中的@autoclosure参数。相反,必须使用()显式调用函数值;调用本身被包装在隐式闭包中,以确保与swift 4模式中的行为相同。

func foo(_ fn: @autoclosure () -> Int) {}
func bar(_ fn: @autoclosure () -> Int) {
  foo(fn)   // ❌ `fn` can't be forwarded and has to be called
  foo(fn()) // ✅
}

11.SR-695在Swift 5模式中,返回Self的类方法不能再被返回非最终具体类类型的方法重写。此类代码不是类型安全的,需要更新。

class Base {
  class func factory() -> Self { ... }
}

class Derived : Base {
  class override func factory() -> Derived { ... }
}

12.SR-5581协议现在可以将它们的符合类型约束为给定类的子类。支持两种等效形式:

protocol MyView : UIView { ... }
protocol MyView where Self : UIView { ... }

请注意,Swift 4.2接受了第二种形式,但它没有完全实现,有时可能会在编译时或运行时崩溃。

swift5适配遇到的问题

升级xcode10.2后代码几乎无需调整,如果你使用了阿里的HandyJson,会因为Swift 5 Type Metadata的变动导致编译失败,在本文编写前该项目已提交更新,但版本号4.2.1未发生变化,意味着使用cocoapods集成的同学使用pod update将无法更新代码。解决方法先移除podfile文件中的handyjson进行pod update,清空cocoapods缓存,添加handyjsonpodfile重新pod upate
或者直接切换到5.0分枝

pod 'HandyJSON', git: '[https://github.com/alibaba/HandyJSON.git](https://github.com/alibaba/HandyJSON.git)' , branch: 'dev_for_swift5.0'

XCode 10.2更新


  1. Interface Builder:双击故事板不再缩放。使用触控板上的捏合手势进行缩放或按住Option并滚动。
  2. LLDB调试:可以使用LLDB调试在闭包内的表达式$0,$1......
  3. LLDB现在支持C的可变长数组
  4. LLDB调试器有一个新的命令别名,v用于“帧变量”命令,用于在当前堆栈帧中打印变量。因为它绕过表达式评估器,v比p或po优先级更高,并且速度更快
  5. Xcode使用SSH配置来确定应该使用哪个SSH密钥来验证远程存储库。
  6. 更多内容浏览下方文档Xcode 10.2 Release Notes

参考文档

1.whats-new-in-swift-5-0
2.swift change Log
3.swift-5-released
4.Xcode 10.2 Release Notes

你可能感兴趣的:(Swift5新特性 & XCode 10.2更新)