Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift-如何定义一个类型约束来保证该类型具有init_Swift_Generics - Fatal编程技术网

Swift-如何定义一个类型约束来保证该类型具有init

Swift-如何定义一个类型约束来保证该类型具有init,swift,generics,Swift,Generics,我有以下代码: struct MyStruct { var v: Int = 1 } func createInstance<T: Any>(type: T.Type) -> T { return type.init() } let myType = MyStruct.self let instance = createInstance(type: myType) 但是如何定义一个约束来保证类型具有init呢 您可以构造一个定制协议来设计init()方法,

我有以下代码:

struct MyStruct {
    var v: Int = 1
}

func createInstance<T: Any>(type: T.Type) -> T
{
    return type.init()
}

let myType = MyStruct.self
let instance = createInstance(type: myType)
但是如何定义一个约束来保证类型具有init呢

您可以构造一个定制协议来设计
init()
方法,并将此协议用作
createInstance
函数中泛型typeholder的类型约束。例如:

protocol SimplyInitializable {
    init()
}

struct MyStruct: SimplyInitializable {
    var v: Int = 1
}

func createInstance<T: SimplyInitializable>(type: T.Type) -> T
{
    return type.init()
}

let myType = MyStruct.self
let instance = createInstance(type: myType)

你能有一个这些结构和类必须实现的
可初始化的
协议吗?你是说它们必须实现一个空协议吗?嗯,有点奇怪,但听起来像是一个很好的把戏:)我来试试。你用
createInstance(type:)
到底想实现什么?标准库中没有
DefaultConstructible
(或类似的)协议是有原因的——没有任何附带的语义,只是可初始化没有什么意义。我建议大家阅读一下。我写了一个框架来轻松持久化结构和类。在load func中,我当然不知道用户类型,所以我需要传递它们并创建它们的实例。@Darion啊,好的,那么您需要一个表示可以编码/解码的内容(而不仅仅是可以构造的内容)的协议。但在这种情况下,您确实需要一个使用一个(或多个)参数的初始化器要求,以便将解码器/字典等传递给类型,以便可以使用其解码的属性值对其进行正确初始化?很好,我错误地使用func init()尝试了协议。谢谢你,我很乐意帮忙。请务必查看Hamish在对您上述问题的评论中链接到的非常相关的博客文章。上面的答案向您展示了如何在技术上实现您所要求的功能,而博客文章讨论了为什么上面的
SimplyInitializable
等协议的语义价值非常低,在Swift的stdlibs中实现是个坏主意。@dfri这些协议的通用价值可能很低,但是c通过提供
new()
generic类型约束非常优雅地解决了这个问题
protocol SimplyInitializable {
    init()
}

struct MyStruct: SimplyInitializable {
    var v: Int = 1
}

func createInstance<T: SimplyInitializable>(type: T.Type) -> T
{
    return type.init()
}

let myType = MyStruct.self
let instance = createInstance(type: myType)
protocol SimplyInitializable {
    init()
}

struct SimpleFactory<T: SimplyInitializable> {
    static func createInstance() -> T {
        return T.init()
    }
}

struct MyStruct: SimplyInitializable {
    var v: Int = 1
}

let instance = SimpleFactory<MyStruct>.createInstance()