好的,我有一个名为 Environment
的协议(protocol)
protocol Environment {
var rootURL: String {get}
}
然后是两个结构体:
struct Production: Environment {
var rootURL = "www.api.mybackend.com/v1"
}
struct Development: Environment {
var rootURL = "www.api.mydevelopmentbackend.com/v1"
}
具有检索环境功能的设置对象:
class Settings {
func getEnvironment<T>() -> T where T: Environment {
let environmentRaw = self.retreiveEnvironmentFromLocalStore()
switch environmentRaw {
case 0:
return Development() as! T
case 1:
return Production() as! T
default:
return Development() as! T
}
}
func retreiveEnvironmentFromLocalStore() -> Int {
//Realm, SQLLite, Core Date, I don't really care for this example.
//Let's just say it defaults to returning 1
}
}
我真的很想继续前进 Protocol Oriented Programming direction 但现在当我在设置对象上调用此函数并尝试使用 rootURL
属性时,编译器提示它无法确定类型。因此,为了更好地理解并找到解决方案:
1) 如果我正在访问由至少知道返回类型符合的协议(protocol)定义的属性,为什么它会关心类型?
2) 结构没有继承。我是否应该定义一个基类而忘记泛型?
3) 我可以使我的 getEnvironment
功能更好吗?我不喜欢 force casting,感觉有点代码味。
4) 我在这里是否正确使用了泛型?
编辑 1:
明确地说,我想要一个函数返回一个我知道将具有此属性的结构。
最佳答案
Am I even using generics correctly here?
不,我不这么认为。您是说 getEnvironment
将返回 T
,它可以是客户端代码指定的任何类型,只要它实现了 Environment
。但是,该方法的实现不会这样做。它只会返回两种Environment
,并且它返回的是哪种类型,并不由客户端代码决定。返回的类型取决于 retreiveEnvironmentFromLocalStore
返回的内容。因此,泛型不适合这种情况。
由于它返回的环境类型是由方法的实现决定的,而不是客户端代码,你应该在这里使用多态性——让它返回一个Environment
:
func getEnvironment() -> Environment {
let environmentRaw = self.retreiveEnvironmentFromLocalStore()
switch environmentRaw {
case 0:
return Development()
case 1:
return Production()
default:
return Development()
}
}
关于swift - 协议(protocol)、结构,但没有具体类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45155005/