swift - 如何调用不带参数的泛型函数?

标签 swift generics

为数组添加一个扩展,它返回第一个 Int 或 String 很容易:

extension Array {
    func firstInt() -> Int? {
        return self.flatMap{$0 as? Int}.first
    }
    func firstString() -> String? {
        return self.flatMap{$0 as? String}.first
    }
}

let a1:[AnyObject?] = [nil, "abc", 3, 4]
let a2:[AnyObject?] = [nil, [3], [ "foo":"bar" ]]
print(a1.firstInt()) // Optional(3)
print(a2.firstInt()) // nil
print(a1.firstString()) // Optional("abc")
print(a2.firstString()) // nil

我可以定义一个通用版本,但我不知道如何调用它,因为它不带任何参数。没有参数,我无法指定类型!

extension Array {
    func firstValueOfType<T>() -> T? {
        return self.flatMap{$0 as? T}.first
    }
}
// I can't figure out how to call this method!

我可以通过添加一个虚拟参数来解决它,但这很丑陋。

extension Array {
    func firstValueLike<T>(_:T) -> T? {
        return self.flatMap{$0 as? T}.first
    }
}

let a1:[AnyObject?] = [nil, "abc", 3, 4]
print(a1.firstValueLike(1)) // Optional(3)
print(a1.firstValueLike("")) // Optional("abc")

如果有人能告诉我如何调用 firstValueOfType 函数(或干净地定义通用函数的替代方法),我将不胜感激。

附加信息

“不能显式特化一个泛型函数”是类似的,但是我的问题因为 Optional 有点复杂。

我从 OOPer 那里得到了一个很好的答案,它甚至包括使用 lazy.filter 而不是 flatMap 的更好的实现。

extension Array {
    func firstValueOfType<T>() -> T? {
        return self.lazy.filter {$0 is T}.first as? T
    }
}

let a1:[AnyObject?] = [nil, "abc", 3, 4]
print(a1.firstValueOfType() as Int?) // Optional(3)
print(a1.firstValueOfType() as String?) // Optional("abc")

非常感谢您的快速支持!

最佳答案

一种方法是将结果分配给具有显式类型的变量。

let i: Int? = a1.firstValueOfType()
print(i) // Optional(3)
let s: String? = a1.firstValueOfType()
print(s) // Optional("abc")

另一个是使用as:

print(a1.firstValueOfType() as Int?) // Optional(3)
print(a1.firstValueOfType() as String?) // Optional("abc")

关于swift - 如何调用不带参数的泛型函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38669179/

相关文章:

ios - Reactive Cocoa - 然后是自定义信号与 UI 信号

c++ - 对给定结构成员应用操作的通用方法

asp.net - ViewState 支持的属性不适用于 List<T>

java - 为什么在填充包含 < 类型元素的集合时行为会有所不同?扩展 T>?

swift - 红色的 Pods 框架(Xcode 无法识别)

Xcode 7.0 启动图像集 "LaunchImage"有 2 个未分配的 child

swift - 使用 Swift 将 UInt8?, String, Int 转换为 String 类型

ios - Swift 全屏导航推送 Segue

java - 复制 ArrayBag 中的所有对象

java - 在匿名类中限定此名称与简单名称