Swift:如何在变量中保存泛型类型的任何可能实例

时间:2015-02-09 09:29:05

标签: swift generics

我正在尝试做的事情是:

public struct HolderOfWrappers
{
    let anyWrappedItem: MyResource<Any>
}

public struct MyResource<A>
{
    let wrappedItem : A
    let convert: String -> A
}

func holdResource<A>( resource: MyResource<A> ) -> HolderOfWrappers
{
    // Error on this line, A is not Any...
    let wrapHolder : HolderOfWrappers = HolderOfWrappers( resource )
    return wrapHolder
}

就目前而言,此代码在上一个holdResource方法中产生编译器错误,我正在尝试构建HolderOfWrappers

Cannot convert the expression's type 'MyResource<A>' to type '(anyWrappedItem: MyResource<Any>)'

这是可以理解的,因为代码表明HolderOfWrappers只能保存为Any类型构建的MyResource,而不是任何可能的类型。我真正追求HolderOfWrappers的是这样的:

public struct HolderOfWrappers
{
    let anyWrappedItem: MyResource<>
}

甚至MyResource<*> - 我试图用这段代码说我想要一个可以容纳任何类型的MyResource的变量。如果我尝试使用任何一种语法,我会得到一个编译器错误,它需要一个类型。

我可能只有anyWrappedItem类型Any,但是您会丢失类型信息以供将来使用。我也不希望HolderOfWrappers是通用的(因为之后我会遇到同样的问题)。

这几乎就像我试图将泛型类型视为anyWrappedItem存储变量的协议一样,这不会因其他原因而起作用......

2 个答案:

答案 0 :(得分:2)

我认为您可以通过在HolderOfWrappers init方法中添加通用参数来执行您想要的操作。基本上,init方法只使用您提供的MyResource生成新的resource,如下所示:

public struct HolderOfWrappers {

    let anyWrappedItem: MyResource<Any>

    public init<A>(resource: MyResource<A>) {
        self.anyWrappedItem = MyResource(wrappedItem: resource.wrappedItem, convert: resource.convert)
    }
}

我认为这会做你想要的。我不知道它是否会因为你初始化一个全新的MyResource而不是只复制一个而变慢。

无论如何,它使得HolderOfWrappers本身不是通用的,并且anyWrappedItem将填充MyResource<Any>,其中resource与{{1}}保持相同的值传入。

答案 1 :(得分:1)

这个怎么样

protocol Wrapper {}

public struct HolderOfWrappers {
    let anyWrappedItem: MyResource<Wrapper>
}

public struct MyResource<A> {
    let wrappedItem : A
    let convert: String -> A
}

func holdResource( resource: MyResource<Wrapper>) -> HolderOfWrappers {
    // Error on this line, A is not Any...
    let wrapHolder : HolderOfWrappers = HolderOfWrappers(anyWrappedItem: resource)
    return wrapHolder
}

当然,缺点是您必须为传递到MyResource的任何类型A执行extension A: Wrapper { }