“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
很混乱,这是什么意思?最后,为什么需要重新声明一个常量(vegetable
为x
),因为它不会改变。没意义!
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 ...
重新声明开关条件(age
或vegetable
)是完全没用的。
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”关键字的含义是啥?的主要内容,如果未能解决你的问题,请参考以下文章