“where”关键字的含义是啥?

Posted

技术标签:

【中文标题】“where”关键字的含义是啥?【英文标题】:What is meaning of "where" keyword?“where”关键字的含义是什么? 【发布时间】:2014-06-03 08:58:26 【问题描述】:

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

let x where x.hasSuffix("pepper")

这是什么意思?

注意:let不用用吗?这让我很困惑.. 这足够x where x.hasSuffix("pepper") 吗?因为,let x 应该已经被分配了。?

更新: 从这里的@Jacky 评论来看,它的含义可能与以下相同。

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

【问题讨论】:

@Leandros 在那个问题上,他们没有明确解释Where 当然,除了 switch 之外,哪里只是 switch 语句中的另一个要求。把它想象成一个开关中的if。 我是这么认为的,但是let不需要用吗?这让我很困惑.. 这足够x where x.hasSuffix("pepper") 吗? 【参考方案1】:

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

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

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

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

你也可以看到x不能是“celery”、“cucumber”或“watercress”,否则会给你不同的结果:

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 if x 的后缀是“pepper”。创建此常量的目的是让您在此之后使用它:

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

编辑 2:

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

switch case 可以将它匹配的一个或多个值绑定到临时 常量或变量,用于案例主体。这是众所周知的 作为值绑定,因为这些值是“绑定”到临时的 案例主体中的常量或变量。

摘自:Apple Inc. “Swift 编程语言”。电子书。 https://itun.es/gb/jEUH0.l

【讨论】:

我是这么认为的,但是let不需要用吗?这让我很困惑.. 这足够x where x.hasSuffix("pepper") 吗?因为,let x 应该已经被分配了。我说的对吗? @Mani 我认为您需要let,因为您实际上是在引入一个新变量x。 (但我可能错了)。 不应该。因为没有人不会用新变量来达到这个条件。对吗? 嘿,这是下一行,1) 介绍在这里case let x where x.hasSuffix("pepper"): 2) 在这里使用它let vegetableComment = "Is it a spicy \(x)?"。这是正确的。 是的,这就是x创建的原因,所以它可以在之后使用。【参考方案2】:
case let x where x.hasSuffix("pepper")

简单的解释是,您不能将String 类型的大小写与.hasSuffix() 匹配,因为它返回Bool。所以,他们给你这个where 模式匹配关键字来使用。它的工作原理是这样的:

    let x 将传递给开关的字符串值复制到常量 x。 where 是一个布尔求值,只有在给定一个真正的布尔值时才会让 case 完成匹配,就像 if 块一样。 hasSuffix() 返回 where 所需的布尔值。

如果传递给开关的字符串变量是var foo。你可以直接这样做:

case foo where foo.hasSuffix("pepper")

您可以将一个真正的布尔值传递给这样的地方,它会毫无用处地工作:

case foo where true

【讨论】:

【参考方案3】:

这是代码的大图:

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"。如果匹配成功,则执行 case 块 let vegetableComment = "Is it a spicy \(x)?",否则继续下一个测试(在本例中为 default:)。

请注意,let 是必需的。这意味着您正在绑定一个新变量x

还要注意和

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

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

【讨论】:

是的。您说这可能就像代码块中带有 if 的情况。但这不是一回事。 if 必须在 where 子句中才能使匹配失败。如果它在代码块中,则测试完成得太晚,即使条件为假,匹配的案例模式也已经成功。 我不是说,按说写代码。相反,它赋予相同的含义。 如果将 let x 替换为 vegetable,则不需要。 case vegetable where vegetable.hasSuffix("pepper"):【参考方案4】:

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 关键字允许你在每个 case 中执行任意代码,这样你就可以在不同的 case 条件下运行不同的代码。如果没有这个,switch 语句只会检查参数和 case 之间的 相等性

有限:每个case条件都比较switch语句条件(age)和case表达式,因为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 表达式中执行代码,因为使用了 where(注意没有使用 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.")

因此,使用let x ... 重新声明开关条件(agevegetable)是完全没用的。


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 参数的其余部分,并声明一个更有用的变量。

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

【讨论】:

【参考方案5】:

"where" 子句在 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)

【讨论】:

以上是关于“where”关键字的含义是啥?的主要内容,如果未能解决你的问题,请参考以下文章

celery中bind = True关键字的含义是啥?

Scala 类定义中受保护关键字的含义是啥?

Angular 2\TypeScript 中 export 关键字的确切含义是啥?

in在sql中是啥意思

JAVA中处理异常的5个常用关键字是啥?代表啥含义?

在SELECT语句中,对查询结果进行排序的子句是啥?能消除重复行的关键字是啥?