Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
391 views
in Technique[技术] by (71.8m points)

casting - Why scala's pattern maching does not work in for loops for type matching?

I'm coding against an API that gives me access to remote file system. The API returns a list of files and directories as list of node objects (parent to file and directory).

I want to work only on a directories, ignoring files. I've tried to use type pattern matching in for loop but it does not work:

for {
    dir: CSDir <- workarea.getChildren() // <-- I'm getting an error here complaining about type conversion
} {
    println(dir)
}

Here is a similar example using scala basic objects to run it without dependencies:

val listOfBaseObjects:List[Any] = List[Any]("a string", 1:Integer);

for (x: String <- listOfObjects) {
  println(x)
}

I end up using a regular pattern matching in side of for loop and that works fine:

// This works fien
for (child <- workarea.getChildren()) {
  child match {
    case dir: CSDir => println(dir)
    case _ => println("do not nothing")
  }
}

Question:

Can you tell me why the first /second example does not work in scala 1.9?

In the "Programming in Scala" the for loop is advertised to use the same pattern matching as the match so it should work.

If the for and match are different it would be great if you could point me to some articles with more details. What about pattern matching in assignment?

Update:

I can't accept an answer that states that it is impossible to skip elements in for loop as this contradicts with the "Prog. in scala". Here is a fragment from section 23.1:

pat <- expr ... The pattern pat gets matched one-by-one against all elements of that list. ... if the match fails, no MatchError is thrown. Instead, the element is simply discarded from the iteration

and indeed the following example works just fine:

scala> val list = List( (1,2), 1, 3, (3,4))
scala> for ((x,y) <- list) { println (x +","+ y) }
1,2
3,4

Why then type matching does not work?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is the long-standing issue 900 and has been discussed many times before. The common workaround is to use something like:

for (y@(_y:String) <- listOfBaseObjects) {
    println(y)
}

A nicer version is provided by Jason Zaugg in the comments to the above-mentioned ticket:

object Typed { def unapply[A](a: A) = Some(a) }

for (Typed(y : String) <- listOfBaseObjects) {
    println(y)
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...