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

时间:2015-12-06 02:52:17

标签: ios swift

我定义了以下结构。

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
}

2 个答案:

答案 0 :(得分: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's answer

单表达式闭包的示例:

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]数组,因此地图需要 类型Person -> Person的闭包,编译器推断

自动返回类型Person

有关更多信息,请参阅“从上下文中推断类型”和“单表达式闭包中的隐式返回” 斯威夫特书中的"Closures"章。

答案 1 :(得分:6)

当使用括号括号使var起作用时,你也必须输入返回类型:

let inActionPersons = persons.map { (var p) -> Person in

    p.active = false
    return p
}