【问题标题】: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") 吗?

标签: ios swift


【解决方案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 模式匹配关键字来使用。它的工作原理是这样的:

  1. let x 将传递给开关的字符串值复制到常量 x。
  2. where 是一个布尔求值,只有在给定一个真正的布尔值时才会让 case 完成匹配,就像 if 块一样。
  3. 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)
      }
      

      【讨论】:

        猜你喜欢
        • 2018-09-13
        • 1970-01-01
        • 2018-05-05
        • 1970-01-01
        • 2015-05-16
        • 2019-07-20
        • 2015-07-13
        • 2018-04-03
        • 1970-01-01
        相关资源
        最近更新 更多