你能有条件地扩展RawRepresentable以符合另一个协议吗?

问题描述 投票:0回答:1

有没有一种方法可以为已经符合 RawRepresentable?

考虑一个基本的例子,这个类可以将基元值存储在一个 sqlite 数据库。

protocol DatabaseStoreable {}

extension Int: DatabaseStoreable {}
extension Double: DatabaseStoreable {}
extension String: DatabaseStoreable {}
extension Data: DatabaseStoreable {}

func storeValue<T: DatabaseStoreable>(_ value: T) {
  ...
}

我想把符合以下条件的任何类型也包括在内。RawRepresentable 哪儿 RawValue: DatabaseStorable:

extension RawRepresentable: DatabaseStoreable where Self.RawValue: DatabaseStoreable {}

但是,这产生了以下错误。

协议 "RawRepresentable "的扩展不能有继承条款。

有没有办法解决这个问题,因为目前我必须用下面的签名声明第二个函数。

func storeValue<T: RawRepresentable>(_ value: T) where T.RawValue: DatabaseStoreable {
  // Calls through to the function above.
}
swift generics protocols
1个回答
0
投票

正如你的错误信息已经告诉你,没有办法向协议添加继承。你只能给对象添加继承。

因此,这是行不通的。

extension RawRepresentable: DatabaseStoreable {}

但是,你可以添加一个扩展,就像这样:

protocol DatabaseStoreable {}

extension Int: DatabaseStoreable {}
extension Double: DatabaseStoreable {}
extension String: DatabaseStoreable {}
extension Data: DatabaseStoreable {}

func storeValue<T: DatabaseStoreable>(_ value: T) {
     print("T store(\(value))")
}

extension RawRepresentable {
    func storeValue<T: DatabaseStoreable>(_ value: T) {
        print("RawRepresentable store(\(value))")
    }
}

enum Test: String {
    case A
    case B
}

class DataBaseStore: DatabaseStoreable {}

let myTest = Test.A
let databaseStore = DataBaseStore()
myTest.storeValue(databaseStore) // prints RawRepresentable store(__lldb_expr_15.DataBaseStore)

1
投票

你可以利用条件一致性来做这样的事情:

extension RawRepresentable where RawValue: DatabaseStoreable {

    func storeValue<T: DatabaseStoreable>(_ value: T) {
        // do stuff
    }
}

enum Foo: String, DatabaseStoreable { 
    case bar
}

Foo.bar.storeValue("test")

顺便说一下,应该是 DatabaseStorable 而不是 DatabaseStoreable.

© www.soinside.com 2019 - 2024. All rights reserved.