GVKun编程网logo

Swift 关联类型(swift关联类型)

1

本篇文章给大家谈谈Swift关联类型,以及swift关联类型的知识点,同时本文还将给你拓展AWESOMESWIFT-swift.libhunt.com-swift类库网站、ChrisLattner对S

本篇文章给大家谈谈Swift 关联类型,以及swift关联类型的知识点,同时本文还将给你拓展AWESOME SWIFT-swift.libhunt.com-swift类库网站、Chris Lattner 对 Swift 3 的总结与对 Swift 4 的展望、Emoji 上的 Swift:换一种视角来理解 Swift 高阶函数、iOS Swift 应用程序随机 EXC_BAD_ACCESS 崩溃:swift_bridgeObjectRetain swift_retain swift::RefCounts等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Swift 关联类型(swift关联类型)

Swift 关联类型(swift关联类型)

译者:靛青K;校对:shanks;定稿:Cee

我想要一个关联类型的圣诞礼物

关联类型系列文章

  • Swift 关联类型
  • Swift 关联类型(续)
  • Swift:为什么选择关联类型

有时候我认为类型理论是故意弄的很复杂,以及所有的那些函数式编程追随者都只是胡说八道,仿佛他们理解了其中的含义。真的吗?你有一篇 5000 字的博客是写关于插入随机类型理论概念的吗?毫无疑问,没有。而且这种理论无法阐述你必须要关注它的原因,以及通过这种高大上的概念能解决什么样的问题。我想把你装进麻袋里,然后把麻袋扔到河里,最后把河丢到一个巨大的中。

我们在讨论什么?当然,关联类型。

当我第一次看到 Swift 泛型的实现时,关联类型 的用法的出现,让我感到很奇怪。

在这篇文章,我将通过类型概念和一些实践经验,这几乎都是我用自己的思考尝试解释这些概念(如果我犯了错误,请告诉我)。

泛型

在 Swift 中,如果我想有一个抽象的类型(也就是创建一个泛型的东西),在类中的语法是这个样子:

class Wat<T> { ... }

类似的,带泛型的结构体:

struct WatWat<T> { ... }

或者带泛型的枚举:

enum GoodDaySir<T> { ... }

但如果我想有一个抽象的协议:

protocol WellINever {
    typealias T
}

嗯哼?

基本概念

protocol 和 class、struct 以及 enum 不同,它不支持泛型类型参数。代替支持抽象类型成员;在 Swift 术语中称作关联类型。尽管你可以用其它系统完成类似的事情,但这里有一些使用关联类型的好处(以及当前存在的一些缺点)。

协议中的一个关联类型表示:“我不知道具体类型是什么,一些服从我的类、结构体、枚举会帮我实现这个细节”。

你会很惊奇:“非常棒,但和类型参数有什么不同呢?”。这是一个很好的问题。类型参数强迫每个人知道相关的类型以及需要反复的指明该类型(当你在构建他们的时候,这会让你写很多的类型参数)。他们是公共接口的一部分。这些代码使用多种结构(类、结构体、枚举)的代码会确定具体选择什么类型。

通过对比关联类型实现细节的部分。它被隐藏了,就像是一个类可以隐藏内部的实例变量。使用抽象的类型成员的目的是推迟指明具体类型的时机。和泛型不同,它不是在实例化一个类或者结构体时指明具体类型,而且在服从该协议时,指明其具体类型。这让我们多了一种选择类型的方式。

有用的

Scala 的创建者 Mark Odersky 在一次访谈中举了一个例子。在 Swift 术语中,如果没有关联类型的话,此时你有一个带有eat(f:Food) 的方法的基类或者协议 Animal ,之后的 Cow 类的没有办法指定 Food 只能是 Grass 。你很清楚不能通过重载这个方法 - 协变参数类型(在子类中添加一个更明确的参数)在大多数的语言都是不支持的,并且是一种不安全的方式 ,当从基类进行类型转换的时候可能得到意料之外的值。

译者注:关于协变,您可以参考这篇文章 Friday Q&A 2015-11-20:协变与逆变 。

如果 Swift 的协议已经支持类型参数,那代码大概是这个样子:

protocol Food { }
class Grass : Food { }
protocol Animal<F:Food> {
       func eat(f:F)
}
class Cow : Animal<Grass> {
    func eat(f:Grass) { ... }
}

非常棒。那当我们需要再增加些东西呢?

protocol Animal<F:Food,S:Supplement> {
    func eat(f:F)
    func supplement(s:S)
}
class Cow : Animal<Grass,Salt> {
    func eat(f:Grass) { ... }
    func supplement(s:Salt) { ... }
}

增加了类型参数的数量是很不爽的,但这并不是我们的唯一问题。我们到处泄露实现的细节,需要我们去重新指明具体的类型。var c = Cow() 的类型就变成了 Cow<Grass,Salt> 。一个 doCowThings 方法将变成 func doCowThings(c:Cow<Grass,Salt>) 。那如果我们想让所有的动物都吃草呢?并且我们没有方式表明我们不关心 Supplement 类型参数。

当我们从 Cow 中获得了创建特别的品种,我们的类就会很白痴的定义成这样:class Holstein<Food:Grass,Supplement:Salt> : Cow<Grass,Salt>

更糟糕的是,一个买食物来喂养这些动物的方法变成这个样子了:func buyFoodAndFeed<T,F where T:Animal<Food,Supplement>>(a:T,s:Store<F>) 。这真的很丑很啰嗦,我们已经无法把 FFood 关联起来了。如果我们重写这个方法,我们可以这样写func buyFoodAndFeed<F:Food,S:Supplement>(a:Animal<Food,Supplement>,s:Store<Food>),但这并不会有作用 - 当我们尝试传入一个 ’Grass’ is not identical to ‘Food’(’Grass’ 和 ‘Food’ 不相同)。再补充一点,注意到这个方法并不关心 Supplement ,但这里我们却不得不处理它。

现在让我们看看如何用关联类型帮我们解决问题:

protocol Animal {
    typealias EdibleFood
    typealias SupplementKind
    func eat(f:EdibleFood)
    func supplement(s:SupplementKind)
}
class Cow : Animal {
    func eat(f: Grass) { ... }
    func supplement(s: Salt) { ... }
}
class Holstein : Cow { ... }
func buyFoodAndFeed<T:Animal,S:Store where T.EdibleFood == S.FoodType>(a:T,s:S){ ... }

现在的类型签名清晰多了。Swift 指向这个关联类型,只是通过查找 Cow 的方法签名。我们的 buyFoodAndFeed 方法,可以清晰的表达商店卖的食物是动物吃的食物。事实上,Cow 需要一个特别的食物类型,而这个具体实现是在 Cow 类里面,但这些信息仍然要在在编译时确定。

真实的例子

讨论了一会关于动物的事情,让我们再来看看 Swift 中的 CollectionType

笔记: 作为一个具体实现,许多 Swift 协议都有带前导下划线的嵌套协议;比如 CollectionType -> _CollectionType 或者 SequenceType -> _Sequence_Type -> _SequenceType。简单来说,当我们讨论这些协议时,我即将打平这些层级。所以当我说 CollectionTypeItemTypeIndexTypeGeneratorType 关联类型时,你并不能在协议 CollectionType 本身中找到这些。

显然,我们需要元素 T 的类型,但我们也需要这个索引和生成器(generator)/计数器 (enumerator)的类型,这样我们才可以处理 subscript(index:S) -> T { get }func generate() -> G<T> 。如果我们只是使用类型参数,唯一的方法就是提供一个带泛型的 Collection 协议,在一个假想的 CollectionOf<T,S,G> 中指明 T S G

其他语言是怎么处理的呢?C# 并没有抽象类型成员。他首先处理这些是通过不支持任何东西而不是一个开放式的索引,这里的类型系统不会表明索引是否只能单向移动,是否支持随机存取等等。数字的索引就只是个整型,以及类型系统也只会表明这一信息。

其次,对于生成器 IEnumerable<T> 会生成一个 IEnumerator<T> 。起初这个不同看起来非常的微妙,但 C# 的解决方案是用一个接口(协议)直接的抽象覆盖掉这个生成器,允许它避免必须去声明特别的生成器类型,作为一个参数,像 IEnumerable<T>

Swift 目的是做一个传统的编译系统(non-VM , non-JIT)编程语言,考虑到性能的需求,需要动态行为类型并不是一个好主意。编译器真的倾向于知道你的索引和生成器的类型,以便于它可以做一些奇妙的事情,比如代码嵌入(inlining)以及知道需要分配多少内存这样奇妙的事情。
唯一的方法就是,通过香肠研磨机在编译时便利出所有的泛型。如果你强迫将它推迟到运行时,这也就意味着你需要一些间接的、装箱和其他的类似比较好的技巧,但这些都是有门槛的。

丑陋的事实

对于抽象类型成员,这儿有个大「坑」:Swift 不会完全地让你确定他们是变量还是参数类型,毕竟这是不必要的事情。只有在使用到泛型约束的时候,你才会用到带有关联类型的协议。

在我们的之前的 Animal 例子中,调用 Animal().eat 是不安全的,因为它只是一个抽象的 EdibleFood ,并且我们不知道这个具体的类型。

理论上,这些代码本应该可以工作的,只要泛型在这个方法上强迫动物吃商店销售的食物的约束,但实际上,当测试它的时候,我遇到了一些 EXC_BAD_ACCESS 的崩溃,我不确定这是情况是不是因为编译器的问题。

func buyFoodAndFeed<T:Animal,S:StoreType where T.EdibleFood == S.FoodType>(a:T,s:S) {
    a.eat(s.buyFood()) //crash!
}

我们没有办法使用这些协议作为参数或者变量类型。这只是需要考虑的更远一些。这是一个我希望在未来 Swift 会支持的一个特性。我希望声明变量或者类型时能够写成这样的代码:

typealias GrassEatingAnimal = protocol<A:Animal where A.EdibleFood == Grass>

var x:GrassEatingAnimal = ...

注意:使用 typealias 只是创建一个类型别名,而不是在协议中的关联类型。我知道这可能有些让人感觉困惑。

这个语法将会让我可以声明持有关于一些动物中部分类型的一个变量,而这里的动物关联的 EdiableFoofGrass。这种语法在这种情况下也很有用:如果在协议中约束其关联类型,但这看起来你可能会进入一个不安全的位置,导致需要考虑的更多一些。如果你开始运行时,有一件事,你需要约束关联类型在这个编译器的定义的协议不能安全的约束任何带泛型的方法(见下文)。

当前情况下,为了获得一个类型参数,你必须通过创建一个封装的结构体”擦除“其关联类型。进一步的警告:这很丑陋。

struct SpecificAnimal<F,S> : Animal {
    let _eat:(f:F)->()
    let _supplement:(s:S)->()
    init<A:Animal where A.EdibleFood == F,A.SupplementKind == S>(var _ selfie:A) {
        _eat = { selfie.eat($0) }
        _supplement = { selfie.supplement($0) }
    }
    func eat(f:F) {
        _eat(f:f)
    }
    func supplement(s:S) {
        _supplement(s:s)
    }
}

如果你曾考虑过为什么 Swift 标准库会包括 GeneratorOf<T>:GeneratorSequenceOf<T>:SequenceSinkOf<T>:Sink…我想现在你知道了。

我上面提到的这个 bug ,如果 Animal 指明了 typealias EdibleFood:Food 之后,即使你给它定义了 typealias EdibleFood:Food ,这个结构体仍然是无法编译的。即使是在结构体中进行了清晰的约束, Swift 将会抱怨 F 不是 Food 。详情可以见 rdar://19371678 。

总结

就像我们之前看到的,关联类型允许在编译时提供多个具体的类型,只要该类型服从对应的协议,从而不会用一堆类型参数污染类型定义。对于这个问题,它们是一个很有趣的解决方案,用泛型类型参数表达出不同类型的抽象成员。

更进一步考虑,我在想,如果采取 Scala 的方案,简单的为 class、struct、enum 以及 protocol 提供类型参数和关联类型两个方法会是否更好一些。我还没有进行更深入的思考,所以还有一些想法就先不讨论了。对于一个新语言最让人兴奋的部分是——关注它的发展以及改进进度。

现在走的更远一些,并且向你的同事开始炫耀类似抽象类型成员的东西。之后你也可以称霸他们,讲一些很难理解的东西。

要远离麻袋。

还有河水。

没有坑,坑是令人惊奇的。

本文由 SwiftGG 翻译组翻译,已经获得作者翻译授权,最新文章请访问 http://swift.gg。

AWESOME SWIFT-swift.libhunt.com-swift类库网站

AWESOME SWIFT-swift.libhunt.com-swift类库网站

https://swift.libhunt.com/categories/688-events

29 Events libraries and projects

  • ORDERED BY POPULARITY
  • ORDER BY DEV ACTIVITY
  •  ReactiveCocoa

      10.0   7.3  Objective-C
    ReactiveCocoa (RAC) is a Cocoa framework inspired by Functional Reactive Programming. It provides APIs for composing and transforming streams of values over time.
  •  RxSwift

      9.9   8.8 L3  Swift
    Microsoft Reactive Extensions (Rx) for Swift and iOS/OSX platform.
  •  PromiseKit

      9.8   8.7 L5  Swift
    async promise programming lib.
  •  ReSwift

      9.6   6.3 L5  Swift
    Unidirectional Data Flow in Swift
  •  Bond

      9.3   8.8 L1  Swift
    a Swift binding framework.
  •  BrightFutures

      8.3   4.7 L4  Swift
    promise and future lib for swift.
  •  Katana

      8.2  8.7 L4  Swift
    Swift apps a la React and Redux.
  •  ReactorKit

      7.8   6.4  Swift
    A framework for reactive and unidirectional application architecture.
  •  ReactKit

      7.4   0.0 L3  Swift
    Swift Reactive Programming.
  •  FutureKit

      6.4  0.7 L2  Swift
    A Swift based Future/Promises Library.
  •  SwiftEventBus

      6.4   3.2 L5  Swift
    A publish/subscribe event bus optimized for iOS.
  •  EmitterKit

      5.7  3.5 L5  Swift
    an implementation of event emitters and listeners in swift.
  •  Signals

      4.9   3.3 L5  Swift
    replaces delegates and notifications.
  •  Safe

      4.9   0.0 L2  Swift
    A modern concurrency and synchronization for Swift.
  •  snail

      4.5   7.1 L5  Swift
    An observables framework for Swift
  •  Reactor

      4.1   2.4 L5  Swift
    Powering your RAC architecture.
  •  VueFlux

      3.8  6.8  Swift
    Unidirectional Data Flow State Management Architecture
  •  SignalKit

      3.7   0.0 L5  Swift
    Swift event and binding framework.
  •  Observable

      3.7   6.2  Swift
    The easiest way to observe values.
  •  When

      3.4   5.4 L5  Swift
    A lightweight implementation of Promises in Swift.
  •  Caravel

      3.3   0.0 L2  Swift
    A Swift event bus for UIWebView and JS.
  •  Future

      2.5   0.0 L4  Swift
    A micro framework providing Future.
  •  NoticeObserveKit

      2.3   0.0 L5  Swift
    NoticeObserveKit is type-safe NotificationCenter wrapper that associates notice type with info type.
  •  Aftermath

      1.8   0.0 L5  Swift
    Stateless message-driven micro-framework in Swift.
  •  Notificationz

      1.6   2.5 L5  Swift
    Helping you own NSNotificationCenter by providing a simple, customizable adapter.
  •  Forbind

      1.2   0.0 L4  Swift
    Functional chaining and Promises in Swift.
  •  ReduxSwift

      1.0   0.0 L5  Swift
    Predictable state container for Swift apps too
  •  PureFutures

      0.7   0.0 L4  Swift
    Futures and Promises library.
  •  SSEventFlow

      0.3  4.4 L5  Swift
    A type safe alternative to NSNotification, inspired by Flux.

Chris Lattner 对 Swift 3 的总结与对 Swift 4 的展望

Chris Lattner 对 Swift 3 的总结与对 Swift 4 的展望

Chris Lattner 写了一篇文章:回顾 Swift 3,展望 Switf 4,以下是这篇文章的关键内容:

  • 开源大有益处,但无法让所有人满意。

  • Swift 3 将在 2016 年秋到来。Swift 3.x 会在 2017 年春公布,Swift 4 会在 2017 年秋发布,这其中不包括修复 bug、提升兼容性之类的小更新(例如 3.0.1)。

  • Swift 4 在交付时一定会保障代码的稳定性,增加容错性、ABI,优化泛型与字符串等等。

  • 语法糖的优先级最低,没有提上日程。

  • 安排进度有些困难。开发的目标并非是对交付的保证。从一开始安排计划与进度就是最主要的事。

下面是全文:


大家好呀,

Swift 3 的正式版已经基本完成,是时候让我们回顾一下这个版本了,从开发过程中汲取经验,并用于总结我们(Swift 社区)在这一年内所做的事。总体上来说,Swift 3 毫无疑问将是一个 amazing 的版本,我们完成了很多出色的工作。感谢所有为它付出的人。相比于立刻着手推进新计划,盘点过去、展望未来同样重要。

提示:这封 email 长得吓人,其中涵盖了各方面的话题。比起直接回复,更好的选择是开一个新话题来讨论。只需在主题上标记“[Swift 4]”即可。

Swift 3 回顾

每年 Swift 的新版本都与前一年完全不同,我希望 Swift 4 能继续保留这个传统。为了每一年都有提升与进步,以下是一些对 Swift 3 的回顾与建议:

  • 开源有许多好处。见证一个充满活力的团队合作得如此之好,大家几乎彻夜为其付出,让人不可思议、充满惊喜。与这样一个才华横溢并充满热情的团队合作,实在是太棒了!

  • 开源也带来挑战。比起“闭源设计”,“开源设计” 进度更慢且更加不可预料,我想这么说应该是公允的。然而,开源的结果明显更好,因此权衡之下开源是值得的。“感谢你们”,献给所有帮助 Swift 发展进化的人。

  • 预估 软件开发的进度(特别是开源项目)依然困难到近乎不可能。我们在着手开发 Swift 3 的时候设立了许多高目标,在后期不得不进行修整。设立一些高目标是好事,但我们需要在沟通上更努力,让其他人知道“目标”不等于“承诺”,避免误导他们。

  • 整个社区得益于在有限的主题上保持专注,因为如果有太多事项同时进行,没有人可以持续跟进所有部分。参与到前面所提的关键讨论中,对核心团队而言非常重要。在 Swift 3 的开发周期中,很多人在代码评审结束前都没有时间来跟进讨论,这是一个问题。

  • 确立清晰的目标是一种解脱。特别是在去年十二月到今年一月,我们大致圈出了那些适合放入 Swift 3 的点子,同时开启了几个项目,这些项目最后远超出我们的能力范围。在后来的版本中,我们确立了几个具体目标(比如“不再加入新计划”),使所有人能更轻松地关注重要事项。

  • 皆大欢喜是不可能的,尤其是在我们讨论优先开发哪些功能时,因为这会降低其他一些功能的优先级。这是一个无解的局面,因为我们并没有办法将所有有意思的工作都放在一个只有一年长的开发周期中。幸运的是,将来“总会有下一个版本”,每一个新版本都会加入一些重大的改进。

在上述回顾的基础上,我们来展望未来!

Swift 发布计划

在接下来一年里,核心团队预计会发布两个主要的版本:2017 年春发布 Swift 3.x,2017 年秋发布 Swift 4。除了主要版本之外,我们也会发布一些小的更新(如 Swift 3.0.1)来修复 Bug,或满足核心库的需求,或其他的 swift.org 的项目。

Swift 4 发布计划

从我们在 Swift 3 中获得的经验来看,我们需要挑出一些重点。对 Swift 4 来说,主要目标是从 3.0 开始要保证交付的代码的稳定性,并为标准库提供 ABI 的稳定性。因此,核心团队决定在接下来的一年中实施两个阶段的计划:

第一阶段:专注于提升代码及 ABI 稳定性,全心投入只完成这项必要的工作。这意味着如果一些功能不会从根本上改变现有语言特性的 ABI ,或是对标准库的 ABI 进行了破坏性的改动,那么现阶段都不会考虑开发它们。举个例子,泛型中的条件一致性(Conditional conformances)是一个附加特性,但由于它会对标准库造成众多更改,我们在第一阶段就要实现它。另一方面,正则表达式不会对现有 ABI 造成影响,也不会给标准库带来大量改动,所以第一阶段不会考虑它。

第一阶段的工作非常重要(下面会详细介绍),所以春季之前我们大概一直会很忙。

第二阶段:当第一阶段功能的设计与实现工作较好得完成之后,我们将基于剩余时间,选择一些大型的功能进行开发。我乐观估计将有剩余时间,来从长长的功能列表中选几个来开发,但具体选哪几个,得看最后剩多少时间。

除了新功能之外,我们也需要重新评估那些在 Swift 3 中尚未实现的、对代码造成破坏性变动的提案。这些提案不一定会被通过,我们需要在 Swift 4 的基础上来评估它们,挨个决定如何处理。

最后,虽然与 Swift 的进步没有特别大的关系,但我想提一提质量与性能问题。核心团队想要进一步提升质量,包括修复编译器的 Bug、改进错误与警告检测功能。性能是开发中另一个需要重视的部分,包括提升编译后的代码质量,改善标准库的实现,加快编译速度等。这些工作在任何开发阶段都需要重视。

Swift 4 第一阶段目标

为了专注于代码与 ABI 的稳定性,核心团队对第一阶段的工作有一个初步的讨论。下面是我们对第一阶段功能排序后的结果:

  • 代码稳定性相关功能:这一部分工作量相对较小,但很重要。举个例子,我们需要类似于“-std=swift3”的编译器标志。我们也需要一个新方法来开启一些大型的功能,这些功能尚在开发,并不稳定,有了这个方法,调试会更简单。

  • 适应力(Resilience):这个功能提供了一种方式,在保证 ABI 稳定性同时,公有 API 可以随时间改进。一个例子,我们不想让 C++ 的“fragile base class” 问题发生在 Swift 中。更多设计与实现上的工作已经在 Swift 3 中完成了,但仍有重要工作未完成,包括模型中用户可见的部分(例如新的属性)。

  • ABI 细节:代码生成模型中仍有大量细节需要审核与改进。这一部分与 Swift 开发更相关,与 Swift 的演进关系不大。

  • 泛型改进需要在标准库的基础上进行:我希望条件一致性能在功能清单中处在最高位置,递归协议要求(recursive protocol requirements)与更强大的关联类型约束能处在随后的相近位置。然而,标准库的开发者们需要大量时间来解析出至关重要的部分,最终消除那些“_”协议,并正确展现标准库中的公有 API。

  • 字符串相关改进:字符串是 Swift 中最重要的基本类型之一。标准库的开发者有很多点子,能改进它的编程范式而不影响到提供 unicode-correct-by-default 范式。我们的目标是在字符串处理上比 Perl 做得更好!

  • 内存所有权模型(Memory ownership model):许多系统开发者,以及想要可预测及确定性的性能(如在实时音频处理中)的人们,都非常希望 Swift 中能有一个(可选的)类似于 Cyclone / Rust 的内存所有权模型。从 Swift 4 的目标上来说,这个功能很重要,因为它从根本上改变了 ABI。这一模型会通知编译器“inout”事件的产生,解释底层“addressors”如何在 ABI 中运作,影响 Swift runtime,并对类型系统及命名管理产生显著影响。

我们对上面这些功能都有了一些想法,但它们在正式成为提案之前仍有很长路要走。我期待它们会在 Swift 4 的早期成为主要讨论内容。不仅如此,由于我们还没有全部找出那些影响 ABI 稳定性的部分,可能还有其他需要增加的条件。最后,我们也可能选择其他一些对 SwiftPM 这个包管理器,或其他对 swift.org 有高价值的小功能。

可能的 Swift 4 第二阶段工作

如我之前所提到的,在这个点上不可能知道还有多少时间留给第二阶段,因此也不知道第二阶段能完成哪些工作。核心团队也希望比 Swift 3 更早完成 Swift 4 开发版的合流,以便在版本发布之前有更多时间修复 BUG,仔细斟酌。

也就是说,我乐观估计我们能够挑一些大家都想要的新功能来开发。为了让你对这些功能有个概念,我列了张表。请注意这并不是开发的计划或承诺,而只是列了一些大家都希望有的功能:

  • 反射:核心团队正致力于为 Swift 添加强大的动态机制。举个例子,Swift 3 中大致完成了数据反射的基础结构(已被用在 Xcode 的 memory debugger 中)。我们应在这些基础结构之上,搭建一些强大的面向用户的 API。同样,我们想要设计并实现动态方法反射的 runtime 与 API 支持。

  • 最重要的并发:Actors、异步 / 等待(async / await)、atomicity、内存模型(memory model)以及相关话题。这些是大家都想要的,因为有了它们,就可以在客户端、服务端等之上开发更多新功能。我们计划在第二阶段正式讨论这件事,但非常明确地告诉大家,新的并发模型在 Swift 4 发布时还无法完成。我们需要超过一年的时间来进行设计与开发,我们也希望把这件事做好做对。需要这么多时间,也是因为在开发内存所有权模型之前能更深入的理解它。

  • 泛型改进:泛型的开发计划中包含来许多激动人心的功能,能改进现有泛型系统。在提升标准库的 ABI 稳定性时并不需要这些功能,但它们会使 Swift 的泛型更加强大易懂。

  • .swiftmodule 的稳定性:在某些方面我们需要使“.swiftmodule”的二进制文件格式稳定下来(或用不同的机制替代它),允许开发第三方的二进制框架。这个工作量很大,并需要标准库 ABI 保持稳定。

  • 新的脚本功能:包括正则表达式、多行字符串字面量等。有了这些功能,Swift 在密集型文本处理任务及搭建 web 等方面会更有吸引力。这些功能也有助于完善字符串模型。

  • 属性行为:这一功能承诺为现有属性模型提供强大的抽象能力。在被推迟的 SE-0030 提案中对它有完整描述。

  • 其他功能:子模块、数值类型间的隐式转换、导入 C++ API、hygenic macro system、尾调用约定、枚举类型遍历、带类型的“thorws”、用户定义属性、抽象方法 / 类、更好的 SIMD 支持、非 @objc 的动态支持、支持数据并行、更高等级的类型...

  • 语法糖:我不会把它们全部列出来,但有大量零散的小提案会经常出现,特别是那些其他语言中出现过、用于解决特定问题的。这些在 Swift 4 开发中都属于最低优先级。

好了,这是一封超长的邮件,列出了一些关于明年要做的事的想法与点子。有一点要提醒一下大家,目前 Swift 3 尚未完成。当对代码的破坏性改动(将要)完成时,需要留有一些时间来修复 Bug 并提升代码质量,这对于正式发布版很重要。

我认为如果我们马上花一些时间来讨论明年开发计划的一些基本事项,会很有帮助,然后再从概念上分解一些第一阶段的特性。只有在对它们有深入了解之后,我们才应该开始写一些提案。核心团队不希望被太多提案淹没,以至于无法跟踪它们的进展,或让我们无法专注于那些高优先级的项目中。

谢谢大家。再次提醒一下,如果大家想要更深入讨论某个话题,请重新开一个分支。

本文由 SwiftGG 翻译组翻译,已经获得作者翻译授权,最新文章请访问 http://swift.gg。

Emoji 上的 Swift:换一种视角来理解 Swift 高阶函数

Emoji 上的 Swift:换一种视角来理解 Swift 高阶函数

不久之前,Iain Delaney 给我发了这一幅图:

这幅由 Steve Luscher 设计的图,其内容来源于 Joey Devilla 的博客 Global Nerdy 中的一篇文章。我觉得这种做法相当有才,让人眼前一亮。

然而,这幅图不是用 Swift 编写的,显然没办法在 Swift 中运行。我决定娱乐一番:我建立了一个 Playground,将大量的 Emoji 字符分配到对应的 Emoji 变量当中,由此构建了一个庞大的列表,然后使用 Swift 的语法让这些例子能够正确运行。

我决定听从 Jaden Geller 在 Twitter 上的所提出的建议,我没有使用便便?来表示 reduce 操作,因为这原先会让人理解为:在每个 reduce 操作执行的时候,都是将便便和一个新的食物合起来一同「吃下」。在 Swift 的版本当中,reduce 将从一个悲伤的表情?开始,最后变得高兴和满足?。

我尝试加了更多的食物种类,看看是否值得扩展一下图片上的内容,但是我发现一旦示例数量超过了原先的 4 种食物,就不够干净和优雅了:

我决定不再使用奶牛?、土豆?、小鸡?和玉米?,我想看一看是否存在一个比 isVegetarian 更好的 filter 选项。比如说孩子们将会选择自己爱吃的食物(往往并不营养):

然后我又想到,那么为什么不再多加一些 Swift 语言的特性呢?于是我决定描述一下可变和不可变项目操作的概念:

以及重复操作:

还有排序操作(虽然我觉得这里可能换用别的食物会更好一些):

当然了,zip 操作同样很赞:

然后还有 mapflatMap 的对比:

很遗憾的是,足球并不是一个合法的字符标识符,所以我无法在足球和橄榄球之间执行 bitcast 操作。这种不一致的 Emoji 字符集让我很不开心。Swift 需要对操作符和标识符进行基于标准的改造。

当我在鼓捣 fatalError 的时候,我发现我的时间都耗费在这里了:

不知道您是否有喜爱的 Swift 功能,想用 Emoji 将其表示出来吗?我已经向大家展示了我的想法。现在,是时候展示您的想法了。

更新:Phil Aaronson 建议还可以使用 emoji 函数。

@ericasadun functions too! pic.twitter.com/IDwDBps2WD

— Phil Aaronson (@phildrone) November 8, 2016

理想情况下,这些示例应当都可以在 Swift Playground 当中编译运行,我同样赞同使用其他 Emoji 来阐述这些功能,即使实现起来相当棘手。

本文由 SwiftGG 翻译组翻译,已经获得作者翻译授权,最新文章请访问 http://swift.gg。

iOS Swift 应用程序随机 EXC_BAD_ACCESS 崩溃:swift_bridgeObjectRetain swift_retain swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>

iOS Swift 应用程序随机 EXC_BAD_ACCESS 崩溃:swift_bridgeObjectRetain swift_retain swift::RefCounts

如何解决iOS Swift 应用程序随机 EXC_BAD_ACCESS 崩溃:swift_bridgeObjectRetain swift_retain swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>

我不断收到来自随机用户的随机崩溃报告。不幸的是,我无法定期重现这一点。用户说崩溃是在 discussionViewController 中随机发生的。所有崩溃报告都有类似的内容:

0   libswiftCore.dylib              0x00000001a53face4 swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::incrementSlow(swift::RefCountBitsT<(swift::RefCountInlinedness)1>,unsigned int) + 60 (atomic:1003)
1   libswiftCore.dylib              0x00000001a53c59e0 swift_retain + 124 (RefCount.h:813)
2   libswiftCore.dylib              0x00000001a5401d60 swift_bridgeObjectRetain + 56 (SwiftObject.mm:585)
3   APPNAME                             0x0000000102b59734 closure #1 in discussionViewController.fetchPostData() + 7916

这是完整的崩溃日志和崩溃的线程:

Hardware Model:      iphone11,6
Process:             APPNAME [11770]
Path:                /private/var/containers/Bundle/Application/.../APPNAME.app/APPNAME
Identifier:          ----
Version:             62 (62)
AppStoretools:       12E262
AppVariant:          1:iphone11,6:13
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           ---- [1824]


Date/Time:           2021-06-17 12:07:01.4346 +1000
Launch Time:         2021-06-17 12:06:56.4993 +1000
OS Version:          iPhone OS 14.6 (18F72)
Release Type:        User
Baseband Version:    3.04.01
Report Version:      104

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x8000000000000010 -> 0x0000000000000010 (possible pointer authentication failure)
VM Region Info: 0x10 is not in any region.  Bytes before following region: 4339515376
      REGION TYPE                 START - END      [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      UNUSED SPACE AT START
--->  
      __TEXT                   102a7c000-102a94000 [   96K] r-x/r-x SM=COW  ...APPNAME.app/APPNAME

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL,Code 0xb
Terminating Process: exc handler [11770]
Triggered by Thread:  3


Thread 3 name:
Thread 3 Crashed:
0   libswiftCore.dylib              0x00000001a53face4 swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::incrementSlow(swift::RefCountBitsT<(swift::RefCountInlinedness)1>,unsigned int) + 60 (atomic:1003)
1   libswiftCore.dylib              0x00000001a53c59e0 swift_retain + 124 (RefCount.h:813)
2   libswiftCore.dylib              0x00000001a5401d60 swift_bridgeObjectRetain + 56 (SwiftObject.mm:585)
3   APPNAME                             0x0000000102b59734 closure #1 in discussionViewController.fetchPostData() + 7916
4   APPNAME                             0x0000000102ad09d4 thunk for @escaping @callee_guaranteed (@guaranteed Data?,@guaranteed NSURLResponse?,@guaranteed Error?) -> () + 132 (<compiler-generated>:0)
5   CFNetwork                       0x00000001a1b0a3dc __40-[__NSURLSessionLocal taskForClassInfo:]_block_invoke + 540 (LocalSession.mm:687)
6   CFNetwork                       0x00000001a1b1c768 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 244 (LocalSessionTask.mm:584)
7   libdispatch.dylib               0x00000001a10d1a84 _dispatch_call_block_and_release + 32 (init.c:1466)
8   libdispatch.dylib               0x00000001a10d381c _dispatch_client_callout + 20 (object.m:559)
9   libdispatch.dylib               0x00000001a10db004 _dispatch_lane_serial_drain + 620 (inline_internal.h:2557)
10  libdispatch.dylib               0x00000001a10dbc34 _dispatch_lane_invoke + 456 (queue.c:3862)
11  libdispatch.dylib               0x00000001a10e64bc _dispatch_workloop_worker_thread + 764 (queue.c:6589)
12  libsystem_pthread.dylib         0x00000001ed04a7a4 0x1ed047000 + 14244
13  libsystem_pthread.dylib         0x00000001ed05174c 0x1ed047000 + 42828

我已验证 discussionViewController.fetchPostData() 不会强制解开任何可选选项,没有 try! 并且在任何地方都使用 [weak self]self?。该函数非常大,所以我很难缩小崩溃发生的范围。

关于Swift 关联类型swift关联类型的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于AWESOME SWIFT-swift.libhunt.com-swift类库网站、Chris Lattner 对 Swift 3 的总结与对 Swift 4 的展望、Emoji 上的 Swift:换一种视角来理解 Swift 高阶函数、iOS Swift 应用程序随机 EXC_BAD_ACCESS 崩溃:swift_bridgeObjectRetain swift_retain swift::RefCounts的相关知识,请在本站寻找。

本文标签: