泛型和约束(“实例方法'...'要求'T'符合'Decodable'`)

时间:2020-07-03 08:48:31

标签: swift generics codable decodable generic-constraints

我有一个通用结构,允许使用不同的类型。我不想将整个结构限制为仅可分解物品。

修复以下错误的最佳方法是什么,其中我尝试仅在T符合Decodable的情况下执行一些代码: implementation ('com.squareup.picasso:picasso:(VERSION)') { exclude group: 'Your OKHTTP package' }

Instance method '...' requires that 'T' conform to 'Decodable'

如您所见,我正在检查是否符合if子句,但这不足以访问受约束的方法吗? :/

3 个答案:

答案 0 :(得分:0)

对我来说,T仅在某些部分符合Decodable,而在其他部分则不需要。我将结构重写为

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 :(得分:0)

首先,在定义结构时,应将T约束为Decodable。其次,您不得在内部将T定义为函数的通用参数,因为编译器不会将T视为结构所遵循的T。相反,它将被视为新的和不同的泛型类型约束(您刚巧使用了相同的名称)。这样做就足够了:

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
  }
}

答案 2 :(得分:0)

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

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的具体版本-即,在那时{{1}可以是Something<Int>Something<String>Something<SomeDecodableType> }将是该具体类型,如您所见,T的各个版本之间没有共同之处,除了T

因此请弄清楚Any的哪些部分确实很常见。