导读:Swift 5.9 的新鲜特性,有什么突出的技术或利于开发者的?请看本文。
Swift 5.9 现已正式发布。除了富有表现力的宏系统和有限形式的 C++ 互操作性之外,Swift 5.9 还引入了参数包、基于所有权的内存管理等新语言特性。
使用if和switch作为表达式
在 Swift 5.9 之前,关键字if和switch只能用作语句,无法将if或switch的结果直接分配给变量或将其作为参数传递。
let bullet =
!willExpand) ? "isRoot && (count ==
count := 0
maxDepth <=
if和switch现在可以用作表达式来用,这意味着这些可怕的嵌套三元表达式现在可以被更具可读性的if条件替换:
let bullet =
if isRoot && (count == !willExpand) { n }else if count == g { "- " ]else if maxDepth <= 9 "" ]else { "v" ]
更好的是,这个新功能还可以与条件绑定一起使用:
let attributedName =
if let displayName, !displayName.isEmpty {AttributedString(markdown: displayName)} else {
"Untitled"
宏系统
这个版本的 Swift 加入了宏系统,宏是使用Swift Syntax库生成代码,用来替换宏调用的 Swift 函数。
Swift 的两种宏概念分别是独立宏,此类宏单独出现,不附加到声明;另一个是附加的宏,它们可被修改并跟随它们的程序实体的声明。从语法上来看,独立宏以为前缀#,附加宏以@作为前缀。如下代码:
#aFreestandingMacro("with argument")
@AttachedMacro<T> struct AStruct {
...
}
当前,Swift 社区已经创建了多个基于宏的工具和框架,包括swift-power-assert、swift-spyable、swift-macro-testing 和 MetaCodable。
参数包
参数包解决了 Swift 泛型类型和函数的限制,但是必须显式命名它们所处理的每个模板化类型。使用参数包,你可以定义接受任意数量类型的泛型类型或者函数。
例如 SwiftUI ViewBuilder,它根据一堆不同的通用函数声明来定义,每个函数声明对应一个View可以传递到构建器中特定数量的类型。你不能在超级视图中添加超过十几个Viewsbody,而需要将它们捆绑到Groups 中。而ViewBuilder相反,使用参数包可以在单个函数中声明行为类型。以下定义了一个函数all来检查其所有参数是否都不是nil:
func all<each Wrapped>(_ optional: repeat (each Wrapped)?) -> (repeat each Wrapped)?
if let (int, double, string, bool) = all(optionalInt, optionalDouble, optionalString, optionalBool) {
print(int, double, string, bool)
}
else {
print("got a nil")
}
所有权
所有权是 Swift 5.9 引入的另一个改变游戏规则的功能。它用于微调性能关键代码中的内存管理。它使用和借用变量和参数的概念以及不可复制的结构和枚举。具体实例,newconsume运算符允许你通过在任何时间点结束变量,并指示编译器标记稍后使用它,以此来控制变量的生命周期:
useX(x) // do some stuff with local variable x
// Ends lifetime of x, y's lifetime begins.
let y = consume x // [1]
useY(y) // do some stuff with local variable y
useX(x) // error, x's lifetime was ended at [1]
// Ends lifetime of y, destroying the current value.
_ = consume y // [2]
useX(x) // error, x's lifetime was ended at [1]
useY(y) // error, y's lifetime was ended at [2]
此外,你可以使用 newborrowing和consuming参数修饰符,根据以下语义显式选择函数用于接收不可变参数的所有权约定:
“如果被调用者借用参数,则调用者保证参数对象将在以下时间内保持活动状态:调用方和被调用方不需要释放它;如果被调用者使用了一个参数,它就负责释放该参数或传递其所有权。”
Swift 所有权的最后一部分是不可复制的,也称为仅移动类型,它始终具有唯一的所有权,以减少堆分配开销,并消除引用计数的需要。
与C++的互操作性
Swift 5.9 还引入了与 C++ 代码的有限形式的互操作性,目前只扩展到某些类型的 API。例如,给定以下 C++ 函数:
std::vector<std::string> generatePromptResponse(std::string prompt);
你可以像这样从 Swift 调用它:
let codeLines = generatePromptResponse("Write Swift code that prints hello world")
.map(String.init)
.filter { !$0.isEmpty }
for line in codeLines {
print(line)
}
结语
Swift 团队表示,与 C++的互操作性仍在不断发展,并且根据现实世界中混合代码库采用的反馈,未来将会发生变化。
另一个并不太重要但肯定受欢迎的新功能是 Swift 支持使用ifandswitch作为变量赋值和返回值的表达式。
作为 Swift 5.9 的最后一点更新,是改进的调试表达式评估器和增强的崩溃处理,它的目标是增强和改善开发人员体验。当崩溃发生时,Swift 运行时现在可以在输出控制台上显示回溯。此外,p和po命令在计算简单表达式时速度更快,并且你可以在条件断点中引用泛型类型参数,例如,仅在使用给定具体类型实例化类型参数时触发断点。
百闻不如一践,文中一些名词特性还需要我们亲自一试方能更透彻。
作者:场长
本文为 @ 场长 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。