2012-04-02 2 views
4

У меня есть список кортежей, и я хотел бы пройти и получить значение каждого элемента.scala новичок с проблемами с кортежами и замыканиями

это код:

scala> val myTuples = Seq((1, "name1"), (2, "name2")) 
myTuples: Seq[(Int, java.lang.String)] = List((1,name1), (2,name2)) 

scala> myTuples.map{ println _ } 
(1,name1) 
(2,name2) 
res32: Seq[Unit] = List((),()) 

До сих пор, так хорошо, но

scala> myTuples.map{ println _._1 } 
<console>:1: error: ';' expected but '.' found. 
    myTuples.map{ println _._1 } 

Я также попытался с:

scala> myTuples.map{ println(_._1) } 
<console>:35: error: missing parameter type for expanded function ((x$1) => x$1._1) 
      myTuples.map{ println(_._1) } 

scala> myTuples.map{ val (id, name) = _ } 
<console>:1: error: unbound placeholder parameter 
     myTuples.map{ val (id, name) = _ } 

scala> myTuples.map{ x => println x } 
<console>:35: error: type mismatch; 
found : Unit 
required: ?{val x: ?} 
Note that implicit conversions are not applicable because they are ambiguous: 
both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A] 
and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A] 
are possible conversion functions from Unit to ?{val x: ?} 
       myTuples.map{ x => println x } 

Объявляя переменную, и с помощью круглых скобок сделал трюк, но я хотел бы знать, почему другие варианты не сработали

это работало нормально

myTuples.map{ x => println("id: %s, name: %s".format(x._1, x._2)) } 

scala> myTuples.map{ x => println("id: %s, name: %s".format(x._1, x._2)) } 
id: 1, name: name1 
id: 2, name: name2 
res21: Seq[Unit] = List((),()) 

scala> myTuples.map{ x => val(id, name) = x; println("id: %s, name: %s".format(id, name)) } 
id: 1, name: name1 
id: 2, name: name2 
res22: Seq[Unit] = List((),()) 

scala> myTuples.map{ x => println(x._1) } 

Что происходит со мной, с моими первыми шагами с Скале, что настаивая немного вы получите то, что вы хотите, но вы не знаете, почему первые варианты вы пытались не работа ...

+1

FWIW, 'map' используется, когда вы хотите, чтобы преобразовать содержимое коллекции. Поскольку вы не заботитесь о результатах, предпочтительным является «foreach». – leedm777

+0

приятный отзыв, и он также делает намного более ясным намерение разработчика – opensas

ответ

6

для вариантов, которые не работали:

scala> myTuples.map{ println _._1 } 

Короткий ответ: В Scala вам всегда нужно использовать parens вокруг аргумента println. Длинный ответ: Скала только содержит скобки для инфиксных методов, то есть код форм object method argument интерпретируется как object.method(argument). Объект не указан, поэтому никаких круглых скобок не выведены. Вы можете увидеть это непосредственно:

scala> println "Boom!" 
<console>:1: error: ';' expected but string literal found. 
     println "Boom!" 
      ^

Далее, myTuples.map{ println(_._1) }. Не сразу понятно, почему это не работает, так как это должно быть эквивалентно myTuples.map{ x => println(x._1) }, который работает. Как показано на рисунке the answers to this question, синтаксис замещающего/частично примененного метода применяется к наименьшему возможному объему. Таким образом, эквивалентный код будет myTuples.map { println(x => x._1) }. Поскольку для scala недостаточно информации для вывода типа x, вы получаете ошибку «Отсутствующий тип параметра».

Относительно myTuples.map{ val (id, name) = _ } заполнители используются в анонимных функциях, тогда как здесь вы инициализируете val.

Затем для myTuples.map{ x => println x } вам также не хватает парсеры.

Наконец, опция, которая сработала для вас myTuples.map{ x => println("id: %s, name: %s".format(id, name)) }, фактически не работала (посмотрите на распечатанные данные). Мое предположение, если вы уже определили id и name в REPL, и это значения, которые печатаются. Теперь ваши рабочие решения отлично работают.

Мое решение делать то, что вы пытаетесь сделать бы:

myTuples foreach { 
    case (id, name) => printf("id: %s, name: %s\n", id, name) 
} 

или

myTuples foreach { 
    x => printf("id: %s, name: %s\n", x._1, x._2) 
} 
+0

Большое спасибо, отличный ответ, и вы правы, решение, которое я дал, не работает, это делает: myTuples.map {x => println («id:% s, name:% s» .format (x._1, x._2))} , а также это: myTuples.map {x => val (id, name) = x; println ("id:% s, name:% s" .format (id, name))} – opensas

+0

Я исправил свое решение – opensas

+2

'myTuples.map {println (_._ 1)}' равнозначно 'myTuples.map {println (x => x._1)} '. Почему это было бы чем-то еще? –

4

Я думаю, что вы хотите что-то вроде:

myTuples map { case(id, name) => println(id+": "+name) } 
Смежные вопросы