泛型 – 如何确定一个泛型是否在Swift中是可选的?

我想使用一个函数来扩展Array,该函数将返回Array中所有非零项的计数。理想情况下,这可以使用任何可选或非可选类型的数组。我尝试了无法编译,崩溃的Xcode或两者的各种事情。我会假设它会像这样:
extension Array {
    func realCount() -> Int {
        var cnt = 0
        for value in self {
            if value != nil {
                cnt++
            }
        }

        return cnt
    }
}

这里Swift抱怨说T不能转换为UInt8。或有时MirrorDisposition或其他随机类。

所以假设有可能,有什么诀窍?

编辑:从Xcode 6 beta 5开始,现在编译,但没有给出预期的结果。如果value!= nil每次都评估为true。

你不能将任意值与nil进行比较(编辑:但请参阅下面的Sulthan的评论;可能是我们应该能够将任意值与nil进行比较;这段落的其余部分今天可能是正确的,但只是由于编译器BUG)。虽然Optional可以使用一些句法糖来应用它,但它只是一个枚举,而nil只是Optional.None。您需要一种类型(可选)的行为和所有其他类型的其他行为。 Swift通过泛型,只是不在扩展。你必须把它变成一个功能:
func realCount<T>(x: [T?]) -> Int {
  return countElements(filter(x,{ $0.getLogicValue() } ) )
}

func realCount<T>(x: [T]) -> Int {
  return countElements(x)
}

let l = [1,2,3]
let lop:[Int?] = [1,nil,2]

let countL = realCount(l) // 3
let countLop = realCount(lop) // 2

这种方法更加灵活。可选只是你想要flatMap的许多类型之一(例如,您可以使用相同的技术来处理Result)。

编辑:您可以通过为您认为“真实”的事物创建协议来进一步。这样你就不必把它限制在可选项。例如:

protocol Realizable {
  func isReal() -> Bool
}

extension Optional: Realizable {
  func isReal() -> Bool { return self.getLogicValue() }
}

func countReal<S:Collection>(x: S) -> S.IndexType.DistanceType {
  return countElements(x)
}

func countReal<S:Collection where S.GeneratorType.Element:Realizable>(x: S) -> Int {
  return countElements(filter(x,{$0.isReal()}))
}

这就是说,如果我通过一系列“可实现”的东西,然后根据他们的规则进行过滤。否则,只要算它们。虽然我可能不会真的使用这个功能(这似乎非常特殊),这个概念很有用。后来的呼叫者可以添加新的“可实现”类型,而不需要修改任何代码(甚至知道它们的实现方式)。这表明如何为不实现协议的事物设置默认行为。

BTW,我在这里使用集合只是因为它们更容易计数(并且我对返回类型有点马虎;注意一个是DistanceType,另一个是Int)。在类型基于集合的函数上获取类型仍然是棘手的(通常会导致编译器崩溃)。我怀疑这将在下一个betas中都有所改善。

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...