簡體   English   中英

Swift 協議通用作為函數返回類型

[英]Swift protocol generic as function return type

我想使用通用協議類型作為函數返回類型,如下所示:

protocol P {
  associatedtype T
  func get() -> T?
  func set(v: T)
}

class C<T>: P {
  private var v: T?
  func get() -> T? {
    return v
  }
  func set(v: T) {
    self.v = v
  }
}

class Factory {
  func createC<T>() -> P<T> {
    return C<T>()
  }
}

但是這段代碼編譯時出現錯誤:

  1. 不能專門化非泛型類型“P”
  2. 函數簽名中未使用通用參數“T”

有沒有辦法用Swift實現類似的功能?

問題是您不能使用語法P<T> P是一個協議,這意味着它不能被視為泛型類型( Cannot specialize non-generic type 'P' ),即使它可能具有給定的associatedtype

事實上,因為它有一個associatedtype ,你現在甚至不能直接使用協議類型本身——你只能將它用作通用約束。

您的問題的一種解決方案是簡單地將您的函數簽名更改為createC<T>() -> C<T> ,因為這正是它返回的內容。

class Factory {
    func createC<T>() -> C<T> {
        return C<T>()
    }
}

我不完全確定將返回類型作為此處的協議會獲得什么。 據推測,您的示例只是對實際代碼的簡化,並且您希望能夠返回符合P的任意實例。 在這種情況下,您可以使用類型擦除

class AnyP<T> : P {

    private let _get : () -> T?
    private let _set : (T) -> ()

    init<U:P where U.T == T>(_ base:U) {
        _get = base.get
        _set = base.set
    }

    func get() -> T? {return _get()}
    func set(v: T) {_set(v)}
}

class Factory {
    func createC<T>() -> AnyP<T> {
        return AnyP(C<T>())
    }
}

Swift 5.1 支持使用 Opaque 類型返回關聯類型。 使用 opaque 類型,您的代碼構建成功。 參考

protocol P {
    associatedtype T
    func get() -> T?
    func set(v: T)
}

class C<T>: P {
    private var v: T?

    func get() -> T? {
        return v
    }
    func set(v: T) {
        self.v = v
    }
}

class Factory {
    func createC<T>() -> some P {
        return C<T>()
}

暫無
暫無

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

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