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

时间:2011-03-25 19:07:21

标签: c# java php python switch-statement

这个问题基于所有使用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 个答案:

答案 0 :(得分:5)

Python 没有switch语句。推荐的替代方案是使用链式if / else链 - 无论如何你应该在你的情况下使用它。

另一个常见的习语是使用地图。在您的情况下,您可以使用(var1,var2)元组来匹配结果。

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

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

答案 1 :(得分: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 :(得分:2)

我认为你可以在Haskell和ML等语言中进行任意的大小写匹配。见Haskell Pattern Matching。有问题的对象仍然是单个对象,但该对象可以是包含任意数量对象的元组。

链接中给出的示例是:

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."

答案 3 :(得分: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;

答案 4 :(得分: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"
}

答案 5 :(得分: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))

答案 6 :(得分:0)

我从来没有见过允许这样的语言,没有。

答案 7 :(得分:0)

当然不在C#中。你会使用if / else if模式来解决这些问题。我不能说任何其他有权威的语言但我99%肯定Java也不允许这样做。谁知道那些疯狂的PHP和Python家伙允许的是什么......

答案 8 :(得分:0)

没有。您必须将一个变量的开关案例嵌套在另一个变量的每个案例中。

答案 9 :(得分:0)

如果你考虑一下,那些语言是不允许的,因为你最终可能会遇到一个以上的案例。

答案 10 :(得分:0)

AFAIK,python没有switch-case。