【问题标题】:How to pass generic protocol as function parameter如何将通用协议作为函数参数传递
【发布时间】:2021-04-26 12:34:27
【问题描述】:

我必须将协议作为参数传递给函数。协议是通用的,具有关联的类型。我找不到这样做的好方法。

我想要实现的基本上是在 json 中存储一个键值对。 所以我有一个通用数据类型协议,它设置/获取值(根据数据类型设置和获取)

在另一个协议中,我想将此通用数据类型协议作为函数参数传递。

protocol Datatype {
    associatedtype dataType
    
    func get(json: JSON) -> dataType?
    func set(json:inout JSON, key: String, value: dataType)
}

class DatatypeString: Datatype{
    
    typealias dataType = String

    func get(json: JSON) -> dataType? {
       return json.stringValue
    }

    func set(json: inout JSON, key: String, value: dataType) {
        json[key] = JSON(value)
    }
}

class DatatypeInt: Datatype{
    typealias dataType = Int
    
    func get(json: JSON) -> Int? {
        return json.intValue
    }
    
    func set(json: inout JSON, key: String, value: Int) {
        json[key] = JSON(value)
    }
}

在下面的代码中,我得到 Protocol 'Datatype' 只能用作通用约束,因为它具有 Self 或关联的类型要求

protocol Final {
    func set<T>(key: String, type: Datatype ,value: T) //getting error
}
class A : Final {
    var root:JSON = [:]
    
    func set<T>(key: String, type: Datatype, value: T) {
        type.set(json: &root, key: key, value: value)
    }
class test {
   let a = A()
   let dataType = DatatypeString()
   a.set("key",datatype, "VALUE")
}

【问题讨论】:

  • 你能说明你想如何实现set吗?
  • Swift 协议是通用的。您的意思是具有关联类型的协议。这不一样,未来可能会有通用协议。
  • @Sweeper 添加了 set 的实现

标签: ios swift generics protocols


【解决方案1】:

您必须使用Datatype 作为通用约束:

func set<T: Datatype>(key: String, type: T ,value: T.dataType)

请注意,您还需要将value 参数的类型更改为T.dataType,以保证类型安全。即你传入的值必须与type参数的dataType类型相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多