代码之家  ›  专栏  ›  技术社区  ›  trundrumbalind

使用动态协议类型进行Swift动态类型初始化

  •  2
  • trundrumbalind  · 技术社区  · 8 年前

    我有许多实现 Resource 协议这定义了它们必须有一个变量 extendedInfo 其符合 ExtendedInfo 协议提供了一种通过json初始化它们的方法 init(json: [String: AnyObject] 。我正在尝试提供一种方法,用JSON动态实例化这些,提供正确类型的 扩展信息 并将其分配给结构 扩展信息 变量然而,我得到了 Argument labels '(json:)' do not match any available overloads 尝试通过 dynamicType

    protocol Resource {
    
        associatedtype ExtendedInfoTypeAlias: ExtendedInfo
    
        var extendedInfo: ExtendedInfoTypeAlias? { get set }
    }
    
    protocol ExtendedInfo {
        init(json: [String: AnyObject])
    }
    
    struct User: Resource {
    
        typealias ExtendedInfoTypeAlias = UserExtendedInfo
    
        let name: String = "Name"
        var extendedInfo: UserExtendedInfo?
    }
    
    struct UserExtendedInfo: ExtendedInfo {
    
        let age: Int?
    
        init(json: [String: AnyObject]) {
            age = json["age"] as? Int
        }
    }
    
    
    let user = User()
    let sampleJSON = ["age": 50]
    
    let userExtendedInfo = user.extendedInfo.dynamicType.init(json: sampleJSON) // Argument labels '(json:)' do not match any available overloads
    user.extendedInfo = userExtendedInfo
    

    伙计们,有什么想法吗?谢谢

    2 回复  |  直到 8 年前
        1
  •  1
  •   Community rcollyer    7 年前

    首先,您不需要显式定义 ExtendedInfoTypeAlias 在结构实现中,您可以让它由您提供的类型推断出来 extendedInfo .

    struct User: Resource {
        let name: String = "Name"
        var extendedInfo: UserExtendedInfo?
    }
    

    其次,您可以只使用给定结构的协议关联类型 dynamicType 以便使用您给定的首字母缩写。例如:

    user.extendedInfo = user.dynamicType.ExtendedInfoTypeAlias.init(json: sampleJSON)
    print(user.extendedInfo) // Optional(Dynamic_Protocols.UserExtendedInfo(age: Optional(50)))
    

    至于你当前的代码为什么不能工作,我怀疑这是因为你得到了 动态类型 从一个可选的,这是防止你调用你的名字缩写。


    我确实发现以下方法有效,即使在 扩展信息 nil . ( This is a bug ).

    user.extendedInfo = user.extendedInfo!.dynamicType.init(json: sampleJSON)

        2
  •  -1
  •   Filipe Dias    8 年前

    更改:

    let user = User()
    

    收件人:

    var user = User()
    

    并尝试以下操作:

    user.extendedInfo = UserExtendedInfo(json: sampleJSON)