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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,784评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,745评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,702评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,229评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,245评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,376评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,798评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,471评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,655评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,485评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,535评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,235评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,793评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,863评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,096评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,654评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,233评论 2 341