在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 -> Person
types的闭包,编译器自动推断返回typesPerson
。
有关更多信息,请参见Swift手册“闭包”一章中的“从上下文中推断types”和“从单一expression式闭包中隐式返回” 。