开发者

Can the switch statement have more than one variable?

The question is based in all the languages that use the switch 开发者_如何学JAVAblock (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...


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.


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.


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


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;


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


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))


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


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


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


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.


AFAIK, python does not have switch-case.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜