我定义了以下结构.
struct Person { var firstName :String var lastName :String var active :Bool }
我创建了一个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
有任何想法吗?
解:
看起来Swift无法推断类型有时候有点蹩脚!这是解决方案:
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 }
Martin R.. 7
在两种情况下,Swift编译器会自动推断闭包的返回类型:
在"单表达式闭包"中,即闭包体仅由单个表达式组成(带或不带显式闭包参数).
如果可以从调用上下文推断出类型.
这些都不适用于
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 }
这就是为什么你必须明确指定返回类型,如Kametrixom的答案.
单表达式闭包的示例:
let inActionPersons = persons.map { p in Person(firstName: p.firstName, lastName: p.lastName, active: false) }
它会用(var p) in
或者编译(p : Person) in
,所以这与闭包参数是否在括号中明确给出无关.
这是一个从调用上下文推断出类型的例子:
let a : [Person] = persons.map { p in var p1 = p p1.active = false return p1 }
结果map()
必须是[Person]
数组,因此map需要一个类型的闭包,Person -> Person
编译器会Person
自动推断返回类型.
有关更多信息,请参阅Swift一书的"闭包"一章中的"从上下文中推断类型"和"单表达式闭包中的隐式返回 ".
在两种情况下,Swift编译器会自动推断闭包的返回类型:
在"单表达式闭包"中,即闭包体仅由单个表达式组成(带或不带显式闭包参数).
如果可以从调用上下文推断出类型.
这些都不适用于
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 }
这就是为什么你必须明确指定返回类型,如Kametrixom的答案.
单表达式闭包的示例:
let inActionPersons = persons.map { p in Person(firstName: p.firstName, lastName: p.lastName, active: false) }
它会用(var p) in
或者编译(p : Person) in
,所以这与闭包参数是否在括号中明确给出无关.
这是一个从调用上下文推断出类型的例子:
let a : [Person] = persons.map { p in var p1 = p p1.active = false return p1 }
结果map()
必须是[Person]
数组,因此map需要一个类型的闭包,Person -> Person
编译器会Person
自动推断返回类型.
有关更多信息,请参阅Swift一书的"闭包"一章中的"从上下文中推断类型"和"单表达式闭包中的隐式返回 ".
当使用参数括号使其var
起作用时,您还必须输入返回类型:
let inActionPersons = persons.map { (var p) -> Person in p.active = false return p }