在Swift中使用Map来更改自定义结构属性

我有以下结构定义。

struct Person { var firstName :String var lastName :String var active :Bool } 

我创build了一个Person的集合,如下所示:

 var persons :[Person] = [] for var i = 1; i<=10; i++ { var person = Person(firstName: "John \(i)", lastName: "Doe \(i)", active: true) persons.append(person) } 

现在我正在尝试使用下面的代码将活动属性更改为false:

 let inActionPersons = persons.map { (var p) in p.active = false return p } 

但是我得到以下错误:

 Cannot invoke map with an argument list of type @noescape (Person) throws 

有任何想法吗?

解:

看起来斯威夫特有时不能推断types有点跛脚! 这是解决scheme:

 let a = persons.map { (var p) -> Person in p.active = false return p } 

这不起作用:

 let a = persons.map { p in var p1 = p p1.active = false return p1 } 

当使用括号作为参数以使var起作用时,您也必须使用返回types:

 let inActionPersons = persons.map { (var p) -> Person in p.active = false return p } 

Swift编译器有两种情况自动推断出闭包的返回types:

  • “单expression式闭包”中,即闭包体只包含一个expression式(有或没有显式闭包参数)。
  • 如果types可以从调用上下文中推断出来

这些都不适用于

 let inActionPersons = persons.map { (var p) in p.active = false return p } 

要么

 let a = persons.map { p in var p1 = p p1.active = false return p1 } 

这就是为什么你必须明确指定返回types,就像在Kametrixom的答案中一样 。

单expression式闭包的例子:

 let inActionPersons = persons.map { p in Person(firstName: p.firstName, lastName: p.lastName, active: false) } 

并且它也可以用(var p) in(p : Person) in编译,所以这与封闭参数是否在括号中明确给出无关。

这里是一个从调用上下文中推断出的types的例子:

 let a : [Person] = persons.map { p in var p1 = p p1.active = false return p1 } 

map()的结果必须是一个[Person]数组,所以map需要一个Person -> Persontypes的闭包,编译器自动推断返回typesPerson

有关更多信息,请参见Swift手册“闭包”一章中的“从上下文中推断types”和“从单一expression式闭包中隐式返回” 。