发布于 2015-06-14 01:53:08 | 369 次阅读 | 评论: 0 | 来源: 网络整理

Where 语句

类型约束中描述的类型约束确保你定义关于类型参数的需求和一泛型函数或类型有关联。

对于关联类型的定义需求也是非常有用的。你可以通过这样去定义where语句作为一个类型参数队列的一部分。一个where语句使你能够要求一个关联类型遵循一个特定的协议,以及(或)那个特定的类型参数和关联类型可以是相同的。你可写一个where语句,通过紧随放置where关键字在类型参数队列后面,其后跟着一个或者多个针对关联类型的约束,以及(或)一个或多个类型和关联类型的等于关系。

下面的列子定义了一个名为allItemsMatch的泛型函数,用来检查是否两个Container单例包含具有相同顺序的相同元素。如果匹配到所有的元素,那么返回一个为trueBoolean值,反之,则相反。

这两个容器可以被检查出是否是相同类型的容器(虽然它们可以是),但它们确实拥有相同类型的元素。这个需求通过一个类型约束和where语句结合来表示:


func allItemsMatch<
    C1: Container, C2: Container
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
    (someContainer: C1, anotherContainer: C2) -> Bool {

        // check that both containers contain the same number of items
        if someContainer.count != anotherContainer.count {
            return false
        }

        // check each pair of items to see if they are equivalent
        for i in 0..someContainer.count {
            if someContainer[i] != anotherContainer[i] {
                return false
            }
        }

        // all items match, so return true
        return true

}

这个函数用了两个参数:someContaineranotherContainersomeContainer参数是类型C1anotherContainer参数是类型C2C1C2是容器的两个占位类型参数,决定了这个函数何时被调用。

这个函数的类型参数列紧随在两个类型参数需求的后面:

  • C1必须遵循Container协议 (写作 C1: Container)。
  • C2必须遵循Container协议 (写作 C2: Container)。
  • C1ItemType同样是C2的ItemType(写作 C1.ItemType == C2.ItemType)。
  • C1ItemType必须遵循Equatable协议 (写作 C1.ItemType: Equatable)。

第三个和第四个要求被定义为一个where语句的一部分,写在关键字where后面,作为函数类型参数链的一部分。

这些要求意思是:

someContainer是一个C1类型的容器。 anotherContainer是一个C2类型的容器。 someContaineranotherContainer包含相同的元素类型。 someContainer中的元素可以通过不等于操作(!=)来检查它们是否彼此不同。

第三个和第四个要求结合起来的意思是anotherContainer中的元素也可以通过 != 操作来检查,因为它们在someContainer中元素确实是相同的类型。

这些要求能够使allItemsMatch函数比较两个容器,即便它们是不同的容器类型。

allItemsMatch首先检查两个容器是否拥有同样数目的items,如果它们的元素数目不同,没有办法进行匹配,函数就会false

检查完之后,函数通过for-in循环和半闭区间操作(..)来迭代someContainer中的所有元素。对于每个元素,函数检查是否someContainer中的元素不等于对应的anotherContainer中的元素,如果这两个元素不等,则这两个容器不匹配,返回false

如果循环体结束后未发现没有任何的不匹配,那表明两个容器匹配,函数返回true

这里演示了allItemsMatch函数运算的过程:


var stackOfStrings = Stack<String>()
stackOfStrings.push("uno")
stackOfStrings.push("dos")
stackOfStrings.push("tres")

var arrayOfStrings = ["uno", "dos", "tres"]

if allItemsMatch(stackOfStrings, arrayOfStrings) {
    println("All items match.")
} else {
    println("Not all items match.")
}
// 输出 "All items match."

上面的例子创建一个Stack单例来存储String,然后压了三个字符串进栈。这个例子也创建了一个Array单例,并初始化包含三个同栈里一样的原始字符串。即便栈和数组否是不同的类型,但它们都遵循Container协议,而且它们都包含同样的类型值。你因此可以调用allItemsMatch函数,用这两个容器作为它的参数。在上面的例子中,allItemsMatch函数正确的显示了所有的这两个容器的items匹配。

最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务