为啥我不能在 switch 语句中使用元组常量作为案例

Posted

技术标签:

【中文标题】为啥我不能在 switch 语句中使用元组常量作为案例【英文标题】:Why can't I use a tuple constant as a case in a switch statement为什么我不能在 switch 语句中使用元组常量作为案例 【发布时间】:2015-04-16 14:35:57 【问题描述】:

我决定使用 Swift 案例语句和元组。它看起来像是该语言最酷的功能之一。

我决定使用月/日/年元组。令我惊讶的是,我不能在 switch 语句中使用常量元组值作为 case。这是一个示例(可以粘贴到 Playground 中并运行)

import UIKit
typealias mdyTuple = (month: Int, day: Int, year: Int)
let joesBirthday: mdyTuple = (month: 6, day: 7, year: 1978)
let someday: mdyTuple = (6, 7, 1978)

switch someday

  //---------
  //The line "case joesBirthday" won't compile.
  //case joesBirthday:
  //  println("Joe was born on this day"
  //---------
case (joesBirthday.month, joesBirthday.day, joesBirthday.year):
  println("Joe was born on this day")
case (joesBirthday.month, joesBirthday.day, let year):
  println("Joe is \(year-joesBirthday.year) today")
default:
  println("Some other day")

注释掉的代码 case joesBirthday: 将无法编译(在 Xcode 6.3 中,如果这很重要的话)。下面的情况(我分别列出了 joesBirthday 元组的所有元素)既难以输入,又难以阅读,确实有效)

我的 Playground 在键入此内容时使 Xcode 崩溃,并在尝试重新启动 Xcode 时再次崩溃,因此我无法报告错误代码。

好的,我终于让 Xcode 停止崩溃(在连续 4 次崩溃之后。耶耶!)错误是“二进制运算符 ~= 不能应用于两个 mdyTuple 操作数。”

为什么要尝试使用~= 操作数?元组不是相等的吗?

是否有一些 clean 替代语法可以让我在 switch 语句的情况下使用常量元组?

【问题讨论】:

如果在switch中使用元组索引会怎样? 喜欢case (joesBirthday.0, joesBirthday.1, joesBirthday.2):?当然,这行得通,但这并不比命名元素语法好。我想直接列出一个元组常量作为 case 值。 【参考方案1】:

您可以像这样为mydTuple 类型实现~= 运算符:

func ~=(a: mdyTuple, b: mdyTuple) -> Bool 
    return a.month ~= b.month && a.year ~= b.year && a.day ~= b.day

这在操场上对我有用...现在,这段代码

switch someday 
case joesBirthday:
    println("one")
default:
    println("two")

打印“一”。

这是运算符的定义:

infix operator ~= 
    associativity none
    precedence 130

并针对以下情况实施:

/// Returns `true` iff `pattern` contains `value`
func ~=<I : IntervalType>(pattern: I, value: I.Bound) -> Bool
func ~=<T>(lhs: _OptionalNilComparisonType, rhs: T?) -> Bool
func ~=<T : Equatable>(a: T, b: T) -> Bool
func ~=<I : ForwardIndexType where I : Comparable>(pattern: Range<I>, value: I) -> Bool

【讨论】:

确实有效。凉爽的。 (已投票)我对 ~= 运算符的作用以及它如何与 case 语句一起工作仍然有些模糊。 这是对 ~= 运算符的一个很好的解释:austinzheng.com/2014/12/17/custom-pattern-matching 它是“模式匹配运算符”,我假设switch语句正在使用它......代码中的注释简要说明了它的作用。 函数的实现中为什么需要使用~=? return a.month == b.month &amp;&amp; a.year == b.year &amp;&amp; a.day == b.day 不会工作并且更简单/更快执行吗? @DuncanC 在这种情况下,我认为您可以使用== 运算符,因为元素是Int,但是对于String 来说是否也一样?这种实现似乎“更安全”

以上是关于为啥我不能在 switch 语句中使用元组常量作为案例的主要内容,如果未能解决你的问题,请参考以下文章

本机 MongoDB:为啥我的 switch 语句不能使用字段名称,而只能使用硬编码值?

在 switch case 语句中,它说“重复的 case 值”作为错误出现。为啥?

switch case语句和if的区别

是否可以在 java switch/case 语句中使用类名? [复制]

为啥我不能将常量数组作为参数传递?

字符串作为switch语句[重复]