我在Swift中玩一些协议/通用的东西,我很好奇为什么下面的代码拒绝编译:
protocol MyProtocol {
func value<T>() -> T
}
class StringImpl: MyProtocol {
var string: String
init() {
self.string = "..."
}
init(string: String) {
self.string = string
}
func value<String>() -> String {
return self.string as! String
}
}
class BoolImpl: MyProtocol {
var value: Bool
init() {
self.value = false
}
init(value: Bool) {
self.value = value
}
func value<Bool>() -> Bool {
return self.value as! Bool
}
}
有特定错误
error: invalid redeclaration of 'value()'
func value<Bool>() -> Bool {
这可能意味着我不能有协议通用方法的不同实现,但是我不清楚为什么会这样。
(我不是说强制类型转换为存在的通用类型阴影)
P.S。对于那些好奇的人,我可能会告诉我,我正在尝试制定一种不会与associatedtype混淆并且在某种程度上还是通用的协议。
答案 0 :(得分:2)
您没问题,错误是var value
,然后重新声明名称为func value<Bool>
的函数,我只是更改了变量名,它就起作用了,错误清楚地表明
错误:“ value()”的无效重新声明
class BoolImpl: MyProtocol {
var bool: Bool
init() {
self.bool = false
}
init(value: Bool) {
self.bool = value
}
func value<Bool>() -> Bool {
return self.bool as! Bool
}
}
答案 1 :(得分:2)
错误:“ value()”的无效重新声明
是这样的。您的方法与变量名称相同,并且返回相同的类型。因此,编译器告诉您这是不合法的。
无论如何,您应该考虑是否确实需要此方法。您可以将此value
属性添加到协议中,看起来您的协议也需要associatedtype
:
protocol MyProtocol {
associatedtype T
var value: T { get set }
}
class StringImpl: MyProtocol {
typealias T = String
var value: T = "..."
init(string: T) {
value = string
}
}
class BoolImpl: MyProtocol {
typealias T = Bool
var value: T = false
init(value: T) {
self.value = value
}
}
然后,如果您只需要对象的值,则只需获取value
属性
someStringImpl.value
someBoolImpl.value
答案 2 :(得分:1)
问题在于“值”变量名与“值”函数名相同
class BoolImpl: MyProtocol {
var storedValue: Bool
init() {
self.storedValue = false
}
init(value: Bool) {
self.storedValue = value
}
func value<Bool>() -> Bool {
return self.storedValue as! Bool
}
}
答案 3 :(得分:1)
每个人似乎都没有抓住重点。
您似乎认为您的采用者
protocol MyProtocol {
func value<T>() -> T
}
...解决泛型。他们不。他们只是重复通用。
例如,考虑一下您的
func value<String>() -> String {
return self.string as! String
}
self.string
是一个字符串。因此,问问自己为什么必须说as! String
。这是因为您像T一样误用String作为占位符名称。如果使用废话,您将得到相同的结果:
func value<Stringgg>() -> Stringgg {
return self.string as! Stringgg
}
也可以编译。您仍未解析通用名称,只需更改其名称即可。您避免关联类型的尝试失败。您的代码可以编译,但永远无法运行。