switch语句可以有多个变量吗?

6

这个问题基于所有使用switch块的编程语言(如C++、C#、PHP、Java、Python等)。所以是否有可能像这样做?

switch (var1, var2)
case  var1 = a:
    something
    break;
case var2 = b:
    something
    break;
case var1 = 0 ,var2 = 1
     etc...
11个回答

5

Python没有switch语句。推荐的替代方案是使用if/else链,这也是你应该在你的情况下使用的。

另一个常见的习惯用法是使用映射。在你的情况下,你可以使用一个(var1,var2)元组来匹配结果。

switch = {
   (1,2): lambda: ..,
   (3,4): lambda: ...,
}
switch[(var1,var2)]

我不确定这是常用的,但至少它是可能的。


2
在Python中,switch语句的“推荐替代方案”应该是字典。 - Voo

4

是/否。

没有使用"switch"语句的传统语言拥有这个功能,但在一些被称为"模式匹配"的东西中存在。

C#、Java、PHP和Python不支持模式匹配(关于PHP我不太确定,如果我错了请纠正我)。

以下是Haskell中模式匹配的示例。模式匹配在很多函数式编程语言中都有应用。

function 1 _ = "first parameter has a one"
function _ 1 = "second parameter is a one"
function _ _ = "I don't know what crazy number you passed in"

当调用该函数时,运行时/编译器/谁都会检查第一个函数是否可以被调用。如果可以,它会返回该值。然后继续寻找适合给定参数的匹配项。下划线 "_" 只是一种表示“任何东西都可以在这里,并且我真的不关心它是什么,所以不要将值绑定到名称”的方式。如果我关心该值,我可以这样做:
function 1 a = "second parameter is " ++ (show a)

现在,由于它通常是自上而下进行的(不像switch语句),因此更类似于if / else而不是switch语句,后者只会跳转到正确的位置。这只是一个非常漂亮的if / else。此外,如果我重新排列文件,使最一般的情况位于文件顶部,则其他情况将被忽略。

您还可以使用模板执行类似的操作,但这只能在编译时起作用。


2
我认为在一些语言中,比如Haskell和ML,你可以进行任意大小写匹配。请参见Haskell模式匹配。所涉及的对象仍然是一个单一对象,但该对象可以是包含任意数量对象的元组。
链接中给出的一个示例是:
describeList :: [a] -> String
describeList list = 
  case list of
   []     -> "The list was empty"
   (x:xs) -> "The list wasn't empty: the first element was " ++ show x ++
             ", and there were " ++ show (length xs) ++
             " more elements in the list."

1
你可以在所有函数参数上进行模式匹配(因此可以匹配多个对象)。 - Jonathan Sternberg
是的,但这在技术上不是一个开关(Haskell中的case)语句 :p - Matthew
1
函数中的模式匹配只是一个 case 语句的语法糖。无论哪种方式,它们更类似于 if/else 语句而不是 switch 语句。 - Jonathan Sternberg

2
"

CHILL 允许它:

"
PROC (b board LOC,m move) EXCEPTIONS (illegal);
DCL starting square LOC:= b (m.lin_1)(m.col_1),
arriving square LOC:= b (m.lin_2)(m.col_2);
DO WITH m;
IF starting.status=free THEN CAUSE illegal; FI;
IF arriving.status/=free THEN
IF arriving.p.kind=king THEN CAUSE illegal; FI;
FI;
CASE starting.p.kind, starting.p.color OF
   (pawn),(white):
      IF col_1 = col_2 AND (arriving.status/=free
      OR NOT (lin_2=lin_1+1 OR lin_2=lin_1+2 AND lin_2=2))
      OR (col_2=PRED (col_1) OR col_2=SUCC (col_1))
      AND arriving.status=free THEN CAUSE illegal; FI;
      IF arriving.status/=free THEN
      IF arriving.p.color=white THEN CAUSE illegal; FI; FI;
   (pawn),(black):
      IF col_1=col_2 AND (arriving.status/=free
      OR NOT (lin_2=lin_11 OR lin_2=lin_12 AND lin_1=7))
      OR (col_2=PRED (col_1) OR col_2=SUCC (col_1))
      AND arriving.status=free THEN CAUSE illegal; FI;
      IF arriving.status/=free THEN
      IF arriving.p.color=black THEN CAUSE illegal; FI; FI;
   (rook),(*):
      IF NOT ok_rook (b,m)
      THEN CAUSE illegal;
      FI;
   (bishop),(*):
      IF NOT ok_bishop (b,m)
      THEN CAUSE illegal;
      FI;
   (queen),(*):
   IF NOT ok_rook (b,m) AND NOT ok_bishop (b,m)
     THEN CAUSE illegal;

2

你可以在Scala(以及任何其他带有模式匹配机制的函数式语言)中做类似于你想要的事情:

def matchTest(var1: Any, var2: Any): Any = (var1, var2) match {
  case (a, _) => "var1 == a"
  case (_, b) => "var2 == b"
  case (0, 1) => "var1 == 0, var2 == 1"
}

2
正如所说,这种模式匹配是函数式语言的典型特征。但你可以在至少支持它的“混合”函数式/OOP语言中找到一些。
以下是F#的一个例子。
let fnc (var1, var2) =
    match (var1, var2) with
        | 2 , _ -> "something"
        | _ , 3 -> "something else"
        | 0, 1  -> "etc ... "
        | a, b -> "I got " + a.ToString() + " and " + b.ToString()

fnc(0, 1) |> printfn "%s" // prints "etc.."

在scala中同样如此

def fnc(var1: Int, var2: Int) : String = 
  (var1, var2) match { 
    case (2, _) => "something" 
    case ( _,3) => "something else"
    case (0, 1) => "etc..."
    case (a, b) => "I got " + a + " and " + b
  } 

println(fnc(0,1))

0

我从未见过允许那样做的语言。


2
函数式语言(F#,ML,Haskell)通常具有此功能,正如Matthew Willis所指出的那样:https://dev59.com/kFXTa4cB1Zd3GeqP25bw#5437014 - Gabe

0
肯定不是在C#中。您可以使用if/else if模式来穿过这些条件。我不能确定其他语言,但我99%确定Java也不允许。不过,谁知道那些疯狂的PHP和Python人允许什么...

2
Python甚至没有switch语句。 :( - Gabe

0
不可以。您需要将一个变量的 switch case 嵌套在另一个 case 中。

0

如果你仔细想一下,编程语言是不允许这样的,因为你可能会得到多个正确的情况。


至少在Java中,您必须在case语句中放置break语句,以防止处理所有的情况。因此,可能有多个情况为真。 - Gilbert Le Blanc
@Gilbert 我并不反对你,但你能否举个例子,说明有多种情况是正确的? - Brent Stewart
很难在评论中回答,因为我不能格式化它,但我能想到的最简单的Java示例是int code = 0; switch (code) { case 0: code = 1; case 1: code = 2; case 2: System.out.println("This was a silly example."); }。 这里有一个更好的例子,在页面的中间位置:http://download.oracle.com/javase/tutorial/java/nutsandbolts/switch.html - Gilbert Le Blanc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接