Can the switch statement have more than one variable?

女生的网名这么多〃 提交于 2019-12-22 05:37:17

问题


The question is based in all the languages that use the switch block (C++, C# PHP , Java , Python and so on). So is it possible to have something like this?

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

回答1:


Yes/No.

No traditional language with a "switch" statement has this. It does exist in something called "pattern matching".

C#, Java, PHP, and Python do not support pattern matching (not completely sure about PHP, but I don't believe it does. Correct me if I'm wrong).

Here's an example in Haskell where pattern matching does exist. Pattern matching is in a lot of functional style languages.

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"

When that function is called, the runtime/compiler/whoever checks it will see if the first function can be called. If it can, it returns that value. It then keeps going until it can find some match that works for the given parameters. The "_" is just a way of saying, "anything can be here, and I really don't care what it is so don't bind the value to a name". If I cared about the value, I could do:

function 1 a = "second parameter is " ++ (show a)

Now since it usually goes top-down (unlike the switch statement), this is more akin to an if/else than a switch statement which just jumps to the correct spot. It's just a very nice looking if/else. Also, if I reordered it so the most general case was at the top of the file, the other cases would be ignored.

You can also do something similar with templates, but that will only work at compile time.




回答2:


Python does not have a switch statement. The recommended alternative is using a chained if/else chain - which is what you ought to be using in your case anyway.

Another common idiom is using a map. And in your case you could use a tuple of (var1,var2) to match against results.

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

I'm not sure this is commonly used, but at least it's possible.




回答3:


I think you can do arbitrary case matching in some languages like Haskell and ML. See Haskell Pattern Matching. The object in question is still a single object, but that object can be a tuple which contains an arbitrary number of objects.

An example given in the link is:

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



回答4:


CHILL allows it:

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;



回答5:


You could do something similar to what you want in Scala (and any other functional language, with a pattern-matching mechanism):

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



回答6:


As said, this pattern matching is typical of functional languages. But you can find some at least "hybrid" functional/OOP ones that support it.

Here's an example in 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.."

and the same in 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))



回答7:


I've never seen a language that allows that, no.




回答8:


Certainly not in C#. You'd use an if/else if pattern to fall through conditions like these. I can't speak for any other language with authority but I'm 99% sure Java doesn't allow it either. Who knows what those crazy PHP and Python guys allow, though...




回答9:


No. You will have to nest the switch case for one variable inside each case of the other.




回答10:


If you think about it, the languages can't allow that because you could end up with more than one case that would be true.




回答11:


AFAIK, python does not have switch-case.



来源:https://stackoverflow.com/questions/5436983/can-the-switch-statement-have-more-than-one-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!