【问题标题】:Switch case with range带范围的开关盒
【发布时间】:2019-03-10 23:15:02
【问题描述】:

我正在学习 Swift,并在观看视频之前尝试自己编写 Ryan Wenderlich 的游戏“Bullseye”。

我需要根据他与目标数字的接近程度来给用户积分。我试图计算差异,然后检查范围并给用户分​​数,这就是我用 If-else 所做的(不能用 switch case 做):

private func calculateUserScore() -> Int {
    let diff = abs(randomNumber - Int(bullsEyeSlider.value))
    if diff == 0 {
        return PointsAward.bullseye.rawValue
    } else if diff < 10 {
        return PointsAward.almostBullseye.rawValue
    } else if diff < 30 {
        return PointsAward.close.rawValue
    }
    return 0 // User is not getting points. 
}

有没有办法更优雅地或使用 Switch-Case 来做到这一点? 我不能只做diff == 0,例如在 switch case 的情况下,因为 xCode 会给我一条错误消息。

【问题讨论】:

  • case 0: return PointsAward.bullseye.rawValuecase 1..&lt;10: return PointsAward.almostBullseye.rawValue 等...
  • 很难看出使用枚举 PointsAward 的意义,因为您只对 rawValue 感兴趣。您是否在代码的其他地方使用枚举?
  • 不,我是 Swift 新手,只是想尝试使用基本的枚举。是的,我同意你的观点,这不是真的需要。
  • 老兄太有趣了,我在 RW 上做同样的靶心应用程序时也用谷歌搜索了这个。好像RW无处不在!

标签: swift switch-statement


【解决方案1】:

你可以相应地返回你想要的值:

switch diff {
case 0:
    print("Bull Eye")
case 1..<10:
    print("Almost Bull Eye")
case 10..<30:
    print("Close")
default:
    print("Too Far")
}

【讨论】:

  • 在 Swift 中的 switch case 会自行中断。如果您需要失败,则需要明确提及。
  • 啊,你知道的。谢谢!!
【解决方案2】:

如果您需要检查一个值是否大于任何数字或在两个值之间使用,可以使用 where 而不是 if 看起来更简洁,这将起作用

func isOutdated(days: Int) -> Outdated {

    var outdatedStatus = Outdated.none

    switch days {
    case _ where days < 5:
        outdatedStatus = .tooLow
    case 5...10:
        outdatedStatus = .low
    case 11...20:
        outdatedStatus = .high
    case _ where days > 20:
        outdatedStatus = .expired
    default:
        outdatedStatus = .none
    }
    return outdatedStatus
}

【讨论】:

  • 请注意,您也可以写成 case ..&lt;5case 20... — 省略下限或上限。
  • @PDK tnx 修复错字:)
【解决方案3】:

在我的情况下,编译器将 CGFloat 视为双精度的封闭范围,因此我必须明确告诉编译器我正在检查 CGFloat 范围。

   var progress: CGFloat!
   switch CGFloat(progress) {
    case 0 ... 0.25:
        barColor = .red
    case 0.25 ... 0.5:
        barColor = .yellow
    default:
        break
    }

【讨论】:

    【解决方案4】:

    这应该可行。

    private func calculateUserScore() -> Int {
        let diff = abs(randomNumber - Int(bullsEyeSlider.value))
        switch diff {
        case 0:
            return PointsAward.bullseye.rawValue
        case 1..<10:
            return PointsAward.almostBullseye.rawValue
        case 10..<30:
            return PointsAward.close.rawValue
        default:
            return 0
        }
    }
    

    它在 The Swift Programming Language 书中的 Control Flow -> Interval Matching 下。

    【讨论】:

      【解决方案5】:

      您必须在 switch 语句中使用范围运算符:

      a...b // 范围从 a 到 b,表示 b 也包括在内

      a..&lt;b // 范围从 a 到 b-1,表示 b 不包括在内

      private func calculateUserScore() -> Int {
          let diff = abs(randomNumber - Int(bullsEyeSlider.value))
          switch diff {
          case 0: return PointsAward.bullseye.rawValue
          case 1..<10: return PointsAward.almostBullseye.rawValue
          case 10..<30: return PointsAward.close.rawValue
          default: return 0
          }
      }
      

      【讨论】:

        【解决方案6】:

        只为你:

        enum PointsAward: Int {
            case close
            case almostBullseye
            case bullseye
        }
        
        private func calculateUserStory() -> Int {
            let bullsEyeSliderValue = 9
            let randomNumber = 100
            let diff = abs(randomNumber - Int(bullsEyeSliderValue))
            switch diff {
            case 0:
                return PointsAward.bullseye.rawValue
            case 0..<10:
                return PointsAward.almostBullseye.rawValue
            case 0..<30:
                return PointsAward.close.rawValue
            default: return 0
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2012-09-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-05
          • 2013-05-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多