簡體   English   中英

Generics 和約束(`實例方法'...'要求'T'符合'Decodable'')

[英]Generics and Constraints (`Instance method '…' requires that 'T' conform to 'Decodable'`)

我有一個通用結構,允許使用不同的類型。 我不想將整個結構限制為僅可解碼項目。

修復以下錯誤的最佳方法是什么,我嘗試僅在 T 符合 Decodable 時執行一些代碼: Instance method '...' requires that 'T' conform to 'Decodable'

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 子句,但這還不足以訪問受約束的方法嗎? :/

對我來說,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
    }
}

首先,您應該在定義結構時將 T 限制為 Decodable 。 其次,您不能在內部將 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
  }
}

您可以使用擴展來定義更受約束的方法:

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將是那個具體的類型,正如你所看到的,有T的各種版本之間沒有任何共同點,除了Any

所以弄清楚Something的哪些部分真正是共同的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM