swift - 协议(protocol)、结构,但没有具体类型

标签 swift generics protocols

好的,我有一个名为 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/

相关文章:

ios - 如何在设备上流畅地进行连续的 Action 过程? (GCD)

ios - 如何在 Swift 中将 UIViewController 转换或类型转换为 AnyClass

mobile - 在没有浏览器的情况下使用协议(protocol) OAuth?

swift - 为什么我的屏幕截图不显示当前 View ?

ios - 解析 CloudKit 错误(CKError)

C#泛型方法和动态类型问题

generics - 使用 AutoFac 注入(inject)通用类型参数

Java泛型方法类型转换

javascript - 如何检测浏览器的协议(protocol)处理程序?

Python 套接字和请求