首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >泛型和约束(``Instance method '...‘要求'T‘符合'Decodable'`)

泛型和约束(``Instance method '...‘要求'T‘符合'Decodable'`)
EN

Stack Overflow用户
提问于 2020-07-03 16:48:32
回答 3查看 1.4K关注 0票数 0

我有一个泛型结构,允许使用不同的类型。我不想将整个结构限制为只有Decodable项。

修复以下错误的最好方法是什么?如果T符合Decodable:Instance method '...' requires that 'T' conform to 'Decodable',我尝试只执行一些代码

代码语言:javascript
复制
struct Something<T> {
    ...

    func item<T>(from data: Data) -> T? where T: Decodable {
        try? JSONDecoder().decode(T.self, from: data)
    }
    
    func getter() -> T {
        let value = ...
        
        if let value = value as? T { return value } // something simple like string
        if let data = value as? Data, T.self is Decodable { // something complex
            return item(from: data) ?? defaultValue // error is thrown here
        }
        
        return defaultValue
    }
}

正如您所看到的,我正在检查if子句的一致性,但这还不足以访问受约束的方法?:/

EN

回答 3

Stack Overflow用户

发布于 2020-07-03 16:57:34

T只需要在某些部分符合Decodable,而不需要其他部分,这对我来说是没有意义的。我会将该结构重写为

代码语言:javascript
复制
struct Something<T: Decodable> {

    func item(from data: Data) -> T?  {
        try? JSONDecoder().decode(T.self, from: data)
    }

    func getter() -> T {
        let value = ...
     
        if let data = value as? Data
            return item(from: data) ?? defaultvalue
        }

        return defaultvalue
    }
}
票数 1
EN

Stack Overflow用户

发布于 2020-07-03 17:36:35

首先,您应该在定义结构时将T约束为Decodable。其次,您不能在内部将T定义为函数的泛型参数,因为编译器不会将它视为结构所遵循的相同T。相反,它将被视为一个新的和不同的泛型类型约束(只是您恰好给出了相同的名称)。这样做就足够了:

代码语言:javascript
复制
struct Something<T: Decodable> {
  
  var defaultValue: T
  var data: Data
  
  func item(from data: Data) -> T? {
    try? JSONDecoder().decode(T.self, from: data)
  }
  
  func getter() -> T {
    item(from: data) ?? defaultValue
  }
}
票数 0
EN

Stack Overflow用户

发布于 2020-07-03 21:59:36

您可以使用扩展来定义更受约束的方法:

代码语言:javascript
复制
struct Something<T> {
   var defaultValue: T

   func getter() -> T {
      return defaultValue
   }
}

extension Something where T: Decodable {
   func getter() -> T {

      // I'm assuming here that you have a property data: Data
      try? JSONDecoder().decode(T.self, from: data) ?? defaultValue
   }
}

目前还不完全清楚如何以有意义的方式使用这种类型。从代码的构造方式来看,valueAny类型。这就是你的意思吗?(我猜不是)

在某个地方,你需要创建一个具体版本的Something --也就是Something<Int>Something<String>Something<SomeDecodableType> --在这一点上,T就是具体的类型,正如你所看到的,除了Any之外,T的不同版本之间没有什么共同之处。

因此,找出Something的哪些部分是真正常见的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62711797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档