什么是"其中"关键词?

时间:2014-06-03 08:58:27

标签: ios swift

我无法理解这句话的确切含义。

let x where x.hasSuffix("pepper")

这是什么意思?

注意:不需要let使用?这让我感到困惑..这是否足够x where x.hasSuffix("pepper")?因为,let x应该已经被分配了。?

更新 来自@Jacky在这里评论,它可能与下面的含义相同。

let x = vegetable 
if (x.hasSuffix("pepper")
 ......

5 个答案:

答案 0 :(得分:18)

该上下文中的where用作pattern matching。从示例:

case let x where x.hasSuffix("pepper"):

x的后缀与"pepper"匹配时,它会设置常量vegetableComment

let vegetableComment = "Is it a spicy \(x)?"

你也可以看到x不能是“芹菜”,“黄瓜”或“水田芥”,否则它会给你一个不同的结果:

case "celery":
    let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
    let vegetableComment = "That would make a good tea sandwich."

因为这些案件在case let x where x.hasSuffix("pepper"):之前。您可以尝试更改它们的顺序并传递值“celery”以查看不同的结果。

修改

根据我的理解,如果 x的后缀是“胡椒”,它会创建一个常量x 。创建此常量的目的是让您在此之后使用它:

let vegetableComment = "Is it a spicy \(x)?"

编辑2:

经过一番研究后,这被称为价值绑定,它被描述为:

  

switch case可以将匹配的值绑定到临时值   常量或变量,用于案例的正文。这是众所周知的   作为值绑定,因为值被“绑定”为临时值   案件正文中的常数或变量。

摘自:Apple Inc.“The Swift Programming Language。”iBooks。 https://itun.es/gb/jEUH0.l

答案 1 :(得分:7)

case let x where x.hasSuffix("pepper")

简单的解释是,您无法将String类型的案例与.hasSuffix()匹配,因为它会返回Bool。因此,他们会为您提供此where模式匹配关键字。它的工作原理如下:

  1. let x将传递给开关的String值复制到常量x。
  2. where是一个布尔评估,如果给出一个真正的bool,就会让案例完成匹配,就像if块一样。
  3. hasSuffix()返回where所需的布尔值。
  4. 如果传入交换机的字符串变量为var foo。你可以改为:

    case foo where foo.hasSuffix("pepper")
    

    你可以将真正的bool传递到这样的地方,它会起作用,无用:

    case foo where true
    

答案 2 :(得分:4)

这是代码的更大视图:

switch vegetable {

... omissis ...

case let x where x.hasSuffix("pepper"):
    let vegetableComment = "Is it a spicy \(x)?"
default:
    let vegetableComment = "Everything tastes good in soup."
}

它的作用是匹配vegetable将其分配给x的值,并测试它是否有后缀"pepper"。如果匹配成功,则执行大小写块let vegetableComment = "Is it a spicy \(x)?",否则继续下一个测试(在本例中为default:)。

请注意let是必要的。这意味着您绑定了一个新变量x

另请注意,它与

不同
case let x:
   if (x.hasSuffix("pepper")
      ...

因为这总是成功并进入case块,而使用where子句意味着如果条件不满足,则匹配失败,下一个case(或default)试过。

答案 3 :(得分:0)

"其中" 子句在swift 2中引入但从未得到开发人员的认可。它用于模式匹配,可以与for-in,switch语句一起使用。它基本上是控制流的一部分,可以在代码中的任何位置使用。一些例子如下

//Example usage in switch
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
    print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
    print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
    print("(\(x), \(y)) is just some arbitrary point")
}

//Example usage in for
let arr = [1,2,3,4]
for value in arr where value != 0 {
    print(value)
}

答案 4 :(得分:0)

Let在此示例中没有用,可以删除:

我修改了OP所引用的代码(可在GuidedTour中使用,以排除let x,以表明let x完全没有用。可读性也得到了改善,因为x不再存在。这是OP(Mani)问题的核心:为什么使用let?答案是在这种情况下,您不应该这样做。

使用x令人困惑,这是什么意思?最后,为什么要重新声明一个常量(vegetablex),因为它不会改变。没意义!

let vegetable = "red pepper"
switch vegetable {
case "celery":
    print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
case vegetable where vegetable.hasSuffix("pepper"):
    print("Is it a spicy \(vegetable)?")
default:
    print("Everything tastes good in soup.")
}
// Prints "Is it a spicy red pepper?"

简单地切换语句

首先,where关键字允许您在每种情况下执行任意代码,以便您可以在不同的情况下运行不同的代码。没有这个,switch语句将只检查参数和大小写之间的相等性

受限:每个案例条件都会将switch语句条件(age)与案例表达式进行比较,因为未使用where

switch age {
case 20:
        print("He is 20")
case 21:
        print("He is 21")
        print("or... he is \(age)")
default:
    print("He is in an unknown age group.")
}

更好:现在,我们可以在case表达式中执行代码,因为使用了位置(注意,不使用 let )。这允许使用范围和更复杂的表达式,这将缩短switch语句的大小:

switch age {
case let age where age < 20:
    print("He is younger than 20")
case age where 20 < age && age < 30:
    print("He is between 20 and 30")
    print("\(age)")
default:
    print("He is in an unknown age group.")
}

未获得任何好处:创建新常数以保存确切值作为切换参数没有用:

switch age {
case let age where age < 20:
    print("He is younger than 20")
case let age_2 where 20 < age_2 && age_2 < 30:
    print("He is between 20 and 30")
    print("\(age == age_2) is True, and will always be True. Useless!")
default:
    print("He is in an unknown age group.")
}

因此,使用age重新声明切换条件(vegetablelet x ...)是完全没有用的。


let实际上有用的地方:

let vegetable在我们没有传递到switch的值的变量或常量的情况下会很有用:

func getVegetable() -> String {
    return "Sweet Potato"
}

switch(getVegetable()) {
case "Pepper":
    print("Spicy!")
case let vegetable where vegetable.hasSuffix("Potato"):
    print("eww potatoes!")
default:
    print("Unknown vegetable")
}

当您要解压缩传递给switch语句的参数时,它会更有用:

let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
    print("on the x-axis with an x value of \(x)")
case (0, let y):
    print("on the y-axis with a y value of \(y)")
case let (x, y):
    print("somewhere else at (\(x), \(y))")
}
// Prints "on the x-axis with an x value of 2"

source (read value binding section)。实际上,它允许您匹配其余的switch参数,并声明一个更有用的变量。

我会将此功能称为可变拆包开关拆包开关拆包或别名部分匹配 >而不是值绑定。声明任何变量时,也将一个值绑定到该变量...“值绑定”是一个毫无意义的宽泛名称。