&引用;表达式类型不明确,没有更多上下文”;Swift闭包错误
我的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 } 然后,我创建了一个包含两个函数的结构,用于获取和设置人员的地址:
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:”参数中。