Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;表达式类型不明确,没有更多上下文”;Swift闭包错误_Swift_Cocoa_Compiler Errors_Swift2 - Fatal编程技术网

&引用;表达式类型不明确,没有更多上下文”;Swift闭包错误

&引用;表达式类型不明确,没有更多上下文”;Swift闭包错误,swift,cocoa,compiler-errors,swift2,Swift,Cocoa,Compiler Errors,Swift2,我的Swift代码中有一个奇怪的类型相关错误: 表达式类型不明确,没有更多上下文 即使我提供了完整的类型信息,这种情况也会发生 这是复制它的代码 我有两个结构: struct Person{ let name_ : String let address_ : Address } struct Address { let street_ : String let city_ : String } 然后,我创建了一个包含两个函数的结构,用于获取和设置人员的地址:

我的Swift代码中有一个奇怪的类型相关错误:

表达式类型不明确,没有更多上下文

即使我提供了完整的类型信息,这种情况也会发生

这是复制它的代码

我有两个结构:

struct Person{
    let name_ : String
    let address_ : Address
}

struct Address {
    let street_ : String
    let city_ : String
}
然后,我创建了一个包含两个函数的结构,用于获取和设置
人员的
地址

struct Lens<A,B> {
    let extract: (A)->B
    let create: (B,A) -> A
}
struct镜头{
让我们摘录:(A)->B
让我们创建:(B,A)->A
}
当我尝试创建一个获取和设置地址的Lens实例时(在后面的例子中,它返回一个具有新地址的新人),我在第一个闭包中得到了错误

let lens : Lens<Person, Address> =
Lens(
    extract: {(p:Person)->Address in
        return p.address_}, // here's the error
    create: {Person($0.name_,
        Address(street_: $1, city_: $0.address_.city_))})
让镜头:镜头=
镜头(
摘录:{(p:Person)->中的地址
返回p.address},//这里是错误
创建:{Person($0.name),
地址(街道:$1,城市:$0.地址:$1.城市})
不仅第一个闭包的参数类型在lens的类型中指定,而且在闭包本身中也指定


发生了什么事???

您对
镜头的初始化将使用如下表单:

let lens = Lens<Person, Address>(
    extract: {p in p.address_},
    create: {(a,p) in Person(name_: p.name_, address_: Address(street_: a.street_, city_: p.address_.city_))})
let lens=镜头(
摘录:{p in p.address},
创建:{(a,p)本人(姓名:p.name,地址:地址(街道:a.street,城市:p.address,城市))}
正如Martin R所指出的,唯一的错误实际上是
create
闭包。调用结构的默认初始值设定项时,默认情况下,需要为所有参数(即使是第一个参数)提供外部名称(=内部名称)(这与常规函数不同,在常规函数中,第一个函数参数可以省略外部名称)。还要确保为初始值设定项提供正确的参数类型


请注意,您不需要在…
中提供闭包类型(
(p:Person)->地址),因为Swift可以从闭包中推断(并期望如此):
p在…
中就足够了(参见上面的示例)。或者,更简洁地说,在闭包中省略显式变量名,并使用
$0
$1
(预期参数)引用,就像在Robs解决方案中一样。

虽然它表明错误在
提取中,但实际上是在
创建中。
$0
$1
是向后的。您指的是
$0.name
,但是
创建
闭包的
$0
B
地址
,但是
名称
个人
的属性。我想你的意思是:

let lens : Lens<Person, Address> = Lens(
    extract: { $0.address_ },
    create: { Person(name_: $1.name_, address_: Address(street_: $0.street_, city_: $1.address_.city_)) }
)
let lens : Lens<Person, Address> = Lens(
    extract: { $0.address_ },
    create: { Person(name_: $0.name_, address_: $1) }
)
然后你可以做:

let lens : Lens<Person, Address> = Lens(
    extract: { $0.address_ },
    create: { Person(name_: $0.name_, address_: Address(street_: $1.street_, city_: $0.address_.city_)) }
)
让镜头:镜头=镜头(
摘录:{$0.address},
创建:{Person(姓名:$0.name,地址:$address(街道:$1.street,城市:$0.address,城市))}
)
或者,也许你的意思是:

let lens : Lens<Person, Address> = Lens(
    extract: { $0.address_ },
    create: { Person(name_: $1.name_, address_: Address(street_: $0.street_, city_: $1.address_.city_)) }
)
let lens : Lens<Person, Address> = Lens(
    extract: { $0.address_ },
    create: { Person(name_: $0.name_, address_: $1) }
)
让镜头:镜头=镜头(
摘录:{$0.address},
创建:{个人(姓名:$0.姓名:$1,地址:$1)}
)

这样,
create
将同时使用所提供地址的街道和城市。(对我来说,使用地址的街道没有意义,但城市没有意义。)

在“create:”闭包中有几个错误:缺少参数标签(
Person(name:…,address:…)
street:$1
没有意义,因为
$1
不是字符串。“extract:”参数是正确的,
{(p:Person)->返回p.Address_}
中的地址是正确类型的闭包。错误仅出现在“create:”参数中。