在Swift中将泛型函数保存为变量

4

给定一个类:

class First<T> {

}

还有一个类First的方法:

func second<U>(closure: (value: T) -> U) {

}

我该如何储存作为参数传递给second的闭包,以便稍后调用它?


可能相关:https://dev59.com/eV8e5IYBdhLWcg3wwMlW - Shadow Of
2个回答

1

您需要在类中声明U,以便您拥有存储的类型:

class First<T,U> {
    var f : ((T) -> U)! = nil
    func second(closure: @escaping (T) -> U) {
        self.f = closure
    }
}

1
那是 Swift 3:Xcode 8,seed 6。请注意,你的 value: 现在是非法的,并且需要使用 @escaping 来表示该函数不是用于立即执行的。 - matt
令人烦恼的是,这似乎是唯一正确的方法。 - Rob Sanders

1
如果仅希望函数second适用于一种类型,那么马特的回答就足够好了。
class First<T, U> {
    typealias ClosureType = (value: T) -> U
    var savedClosure: ClosureType? = nil
    func second(closure: ClosureType) {
        savedClosure = closure
    }
}

这并不实际回答你提出的问题!
问题在于:你无法存储未知类型的值。但是,如果该类型符合已知协议,则可以保存它。
protocol P {}

class First<T> {
    typealias ClosureType = (value: T) -> P
    var savedClosure: ClosureType? = nil
    func second<U: P>(closure: (value: T) -> U) {
        savedClosure = closure
    }
}

该协议甚至可以是“没有协议”,其别名为关键字Any
class First<T> {
    typealias ClosureType = (value: T) -> Any
    var savedClosure: ClosureType? = nil
    func second<U>(closure: (value: T) -> U) {
        savedClosure = closure
    }
}

但我们不知道您想要做什么,所以对于您的问题有多个答案......例如,也许您想为每种类型存储单独的闭包?

class First<T> {
    typealias ClosureType = (value: T) -> Any
    var savedClosures = [String: ClosureType]()
    func second<U>(closure: (value: T) -> U) {
        savedClosures[String(U)] = closure
    }
}

无论如何,真正的问题是:“你真的需要这样做吗?有没有一些简单的改变可以避免这种需要?”


因此,我想保存一个包含两个泛型的闭包的原因是为了提供一些映射功能。即使将 T 映射到 U。你的解决方案的问题在于,每次我想要将例如 int 映射到 string 的时候,我都必须实现自己版本的字符串,以符合类型 P 的协议。但创意值得点赞! - Rob Sanders
你可以使用一个空扩展 extension String: P {},但如果使用 Any 的话就不需要了,因为“所有类型都隐式地符合”它。 - NiñoScript

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接