Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The type cast as part of the switch is really cool, I hadn't seen that before.

    switch v := v.(type) {
    case string:
        w.Write(int32(len(v)))
        w.Write([]byte(v))
    default:
        w.err = binary.Write(w.w, binary.LittleEndian, v)
    }
Great way to alter control flow based on the type, without a ton of ugly casts cluttering things up.


This is why I love pattern matching in languages that support it - typing is just one of the things on which they can switch. As the Scala website puts it (paraphrasing), "Pattern matching is switch on steroids!"

Here is how you would return all leaf values in a binary tree in Scala:

    case class Node
    case class Fork(left: Node, right: Node) extends Node
    case class Leaf(value: Int) extends Node

    def getValues(node: Node): List[Int] = node match {
    	    case f: Fork => getValues(f.left) ++ getValues(f.right)
	    case l: Leaf => List(l.value)
    }
EDIT: Would actually be more idiomatic in Scala to extract the values from the case classes rather than just matching on type...yet another wonderful feature of pattern matching. Coded as follows:

    def getValues(node: Node): List[Int] = node match {
	    case Fork(left, right) => getValues(left) ++ getValues(right)
	    case Leaf(value) => List(value)
    }


Here's the tail-call optimized version, won't blow the stack. Technically idiomatic, but way too cryptic to be serious code. Clearly I need more outlets for writing Scala. =)

    @tailrec
    def getValuesFromNode(node: Node, accValues: List.empty[Int], nodeList: List.empty[Node]): List[Int] = node match {
      case Fork(left, right) => getValuesFromList(accValues, nodeList ++ List(left, right))
      case Leaf(value) => getValuesFromList(accValues ++ List(value), nodeList)
    }

    @tailrec
    def getValuesFromList(accValues: List.empty[Int], nodeList: List.empty[Node]): List[Int] = nodeList match {
      case x :: xs => getValuesFromNode(x, accValues, xs)
      case _ => accValues
    }


It's used in Kotlin and Ceylon, but the example above is really just a weak way to make up for the absence of overloading.

The compiler should be making these checks, not the developer.


Of all the code in there this part confused me. What exactly is being switched on? It looks like v is being reassigned to the type of v, then the type of v is written out (instead of the value).


It's being switched on the type of v (string or other, in this case), though in a more complex case you could easily have several different types. The assignment basically redefines v to be the matched type inside the case statement. You could easily just add a "sv := v.(string)" as the first statement of "case string", then use sv in place of v within that block, but this does read much cleaner.

I think it gets more interesting when using several, often complex (struct) types in the same switch statement.


> It looks like v is being reassigned to the type of v,

v is not being reassigned, it is being declared (note := rather than =). But its a little complicated, because type switches are a special syntax construct that is similar to, but different than, regular expression switches. See, "Type switches" in the language reference [1]

[1] you'll have to scroll down a little within the section on Switch statements: http://golang.org/ref/spec#Switch_statements


"type" is a magic word in Go, and in that example. It's highly idiomatic -- it's inconsistent with the rest of the language (Using "type" instead of an actual type), but it makes sense once you memorize the idiom. Sort of perlish -- there are two different operations that look basically the same, and the correct one is chosen based on context (in this case, the context is "is there a type name, or "type" literally?)

Perhaps it would have been cleaner to use "*" or some other operator symbol instead of the reserved word "type"


> "type" is a magic word in Go, and in that example.

Specifically, type switches are a specific syntax construct that look very similar to normal switches, but switched on something that looks like a type assertion with "type" in place of an actual type.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: