Swift 5.0的新功能

了解Swift 5.0中可用的关键功能。Swift 5.0的主要目标是使语言达到ABI稳定性。 这将使稳定的Swift运行时能够由OS供应商部署,并且可以通过可执行文件和库进行链接。

Swift 5的新改进:

  1. 增强字符串文字定界符以支持原始文本(SE-0200)
  2. 将结果添加到标准库(SE-0235)
  3. 修复ExpressibleByStringInterpolation (SE-0228)
  4. 引入用户定义的动态“可调用”类型(SE-0216)
  5. 处理将来的枚举案件(SE-0192)
  6. 拼合由“ try?”产生的嵌套可选内容 (SE-0230)
  7. isMultiple添加到BinaryInteger (SE-0225)

特别说明:

  1. 在运行iOS 12.2,watchOS 5.2和tvOS 12.2的设备的构建变体中,Swift应用程序不再包含用于Swift标准库的动态链接库和Swift SDK覆盖。 因此,在部署用于使用TestFlight进行测试或为本地开发分发而精简应用程序存档时,Swift应用程序可以较小。
  2. 为了减少Swift元数据占用的空间,现在,在Swift中定义的便捷初始化程序正在调用Objective-C中定义的指定初始化程序时,才提前分配一个对象。

阅读这些改进说明,以获取更深入的知识,以增强您对即将发生的变化的了解。

增强字符串文字定界符以支持原始文本(SE-0200)

扩展定界符

我们的设计添加了可定制的字符串定界符。 您可以使用一个或多个# (磅,数字符号,U + 0023)字符填充字符串文字:

 "This is a Swift string literal" 
 #"This is also a Swift string literal"# 

自定义转义分隔符

使用自定义边界定界符的字符串在前导反斜杠后镜像其英镑符号,如以下示例所示,它们产生的结果与前面的字符串文字相同:

 #"This string has an \#(interpolated) item"# 
 ####"This string has an \####(interpolated) item"#### 

将结果添加到标准库

Result是当前和未来竞争性错误处理问题之间的务实妥协。

用法

异步API

这可能很难优雅地使用以下API的结果:

  URLSession.shared.dataTask(with:url){(data,response,error)in 
警卫错误!=无其他{self.handleError(error!)}

保护let数据=数据,let响应=响应else {return //不可能吗? }

handleResponse(响应,数据:数据)
}

尽管这段代码只有几行,但它暴露了Swift完全缺乏对异步API进行自动错误处理的情况。 error不仅被强行解开(或使用稍微不太优雅的if语句进行了处理),而且创建了可能不可能的场景。 如果responsedata nil怎样? 可能吗 事实并非如此,但是Swift目前缺乏表达这种可能性的能力。 在同一场景中使用Result可以得到更优雅的代码:

  URLSession.shared.dataTask(with:url){(//结果:Result )//为说明目的添加了类型。 
切换结果{
案例让.success(success):
handleResponse(success.response,数据:success.data)
案例让.error(错误):
handleError(错误)
}
}

该API准确表达了预期的结果(错误,数据和响应,从不全部或全无),并使它们的处理更加清晰。

分离错误

能够以允许开发人员在错误源之间进行歧义消除的方式运行throw功能的功能有时很有用,尤其是在错误不包含执行错误操作所需的信息或者开发人员不希望这样做的情况下。实施这样的检查。 例如,如果我们需要消除在读取文件时可能出现的错误之间的歧义:

 做{ 
handleOne(尝试String(contentsOfFile:oneFile))
} {
handleOneError(错误)
}

使用Result可以更清楚地表达这种情况:

 让一个=结果{试试String(contentsOfFile:oneFile)} 
  handleOne(一个) 

Result上附加的便捷API可以使许多情况变得更加优雅。

修复ExpressibleByStringInterpolation

插值字符串文字包含一个或多个嵌入式表达式,以\()分隔。 在运行时,将对这些表达式求值并与字符串文字串接以产生值。 它们通常比在字符串文字,串联运算符和任意表达式之间切换的代码更具可读性。

插入的字符串将转换为以下代码:

  1. 初始化关联的StringInterpolation类型的实例,并将总文字段大小和插值计数作为参数传递。
  2. 一次调用其appendLiteral(_:)方法以附加文字值,并appendInterpolation附加其插值。 插值被视为调用括号,即\(x, with: y)成为对appendInterpolation(x, with: y)的调用。
  3. 将实例传递给init(stringInterpolation:)以产生最终值。

以下是与编译器生成的代码大致相似的代码:

  //语义表达式:“你好\(名称)!” 
字符串(stringInterpolation:{
var temp = String.StringInterpolation(literalCapacity:7,InterpolationCount:1)
temp.appendLiteral(“ hello”)
temp.appendInterpolation(名称)
temp.appendLiteral(“!”)
返回温度
}()

引入用户定义的动态“可调用”类型

这是SE-0195的后续版本—引入了用户定义的“动态成员查找”类型,该类型在Swift 4.2中提供。 它引入了一个新的@dynamicCallable属性,该属性使用常规语法将类型标记为“可调用”。 它是简单的语法糖,它允许用户编写:

  a = someValue(关键字1:42,“ foo”,关键字2:19) 

并由编译器将其重写为:

 一个= someValue.dynamicallyCall(withKeywordArguments:[ 
“ keyword1”:42,“”:“ foo”,“ keyword2”:19
])

处理未来的枚举案例

切换非冻结枚举时,与其匹配的switch语句必须包含一个全用例(通常为default或“忽略” _模式)。

 切换借口{ 
案例.eatenByPet:
//…
案例.thoughtItWasDueNextWeek:
//…
}

否则,将在Swift 5中产生警告。如果实际遇到未知的枚举,则程序将在运行时捕获。

这是一个更复杂的示例:

 切换借口{ 
案例.eatenByPet:
//具体的已知情况
@未知案例_:
//编译器无法识别的任何情况
案件 _:
//编译器*知道的任何其他情况,
//如.thoughtItWasDueNextWeek
}

拼合由“ try?”产生的嵌套可选内容

在Swift 5中, try? someExpr() try? someExpr()将反映foo?.someExpr()的行为:

  • 如果someExpr()产生一个非可选的值,它将被包装在一个Optional中。
  • 如果someExpr()产生Optional ,则不添加其他可选性。

这导致以下try?类型的更改try? 表达:

  // Swift 4:“ Int ??” 
// Swift 5:“ Int?”
让结果=尝试? database?.countOfRows(匹配:谓词)

  // Swift 4:“ String ??” 
// Swift 5:“字符串?”
让myString =试试? 字符串(数据:someData,编码:.utf8)

// Swift 4:'[String:Any] ??'
// Swift 5:“ [String:Any]?”
让dict =尝试? JSONSerialization.jsonObject(with:data)as? [字符串:任何]

当子表达式产生非可选时,整体类型没有变化。

isMultiple添加到BinaryInteger

Swift 5在BinaryInteger协议中添加了func isMultiple(of other: Self) -> Bool

  // Apple / swift中的KeyPath.swift 
_sanityCheck(bytes> 0 && bytes.isMultiple(of:4),“容量必须是4字节的倍数”)

Swift 5.0是Swift的最新版本,但是以前的swift版本也包含了许多强大的功能。

希望本文对希望了解swift即将发布的版本的新内容的人有用,请❤️将这篇文章推荐给其他人😊。 让我知道您的反馈。 🙂

参考文献

  1. https://github.com/apple/swift-evolution/blob/master/proposals/0200-raw-string-escaping.md
  2. https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md
  3. https://github.com/apple/swift-evolution/blob/master/proposals/0228-fix-expressiblebystringinterpolation.md
  4. https://github.com/apple/swift-evolution/blob/master/proposals/0216-dynamic-callable.md
  5. https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
  6. https://github.com/apple/swift-evolution/blob/master/proposals/0230-flatten-optional-try.md
  7. https://github.com/apple/swift-evolution/blob/master/proposals/0225-binaryinteger-iseven-isodd-ismultiple.md