2012-05-20 3 views
2

Вы можете создать новый список в Scala, используя:Почему функция cons вызвана экспликацией в Int в Scala?

1 :: 2 :: Nil 

В моем понимании это может переписать:

Nil.::(2.::(1)) 

В основном потому, что :: fixty, но если я пишу:

Nil :: 1 :: 2 

Я получаю «значение :: не является членом Int», что полностью ожидаемо, потому что в scaladoc Int нет ::, но я не могу понять, почему, если я переведу его так:

1.::(2.::(Nil)) 

Он работает, как получение продукции:

List(1.0, 2.0) 

Похоже scalac авто бросает 1 и 2 к типу, отличной от Int. Это верно? Если да, то почему это происходит, и какой это странный тип?

ответ

6

Это смешно.

Ваше выражение

1.::(2.::(Nil)) 

в настоящее время анализируется компилятором, как

1. :: (2. :: (Nil)) 

, который, так как :: является правоассоциативной, такая же, как

1. :: 2. :: Nil 

, который, так как 1. является действительным способом написания Double, является так же, как

1.0 :: 2.0 :: Nil 

, которая является юридическим выражением для построения List[Double]

List(1.0, 2.0) 
+0

Значит, это ошибка scala 2.9.2? Или так оно и должно работать? – rsan

+2

Это не ошибка. Это совершенно правильное выражение. Это просто немного забавно, когда вы оставляете места. – dhg

+0

Почему «1. :: (2. :: (Nil))» анализируется на «1.0 :: 2.0 :: Nil»? Я, однако, что операторы, оканчивающиеся на: имеют обратную фиксацию. – rsan

0

Вы пишете, что выражение

1 :: 2 :: Nil 

можно переписать в виде

Nil.::(2.::(1)) 

T его не совсем правильно, потому что 2. разобран как Double. Это можно было бы исправить добавлением скобок вокруг 2, но затем компилятор все еще жалуется, поскольку класс Int не поддерживает метод ::!

Данное выражение можно записать в виде

(Nil.::(2)).::(1) 

Другой выражение, которое у вас есть

1.::(2.::(Nil)) 

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

1 .::(2 .::(Nil)) 
(1).::((2).::(Nil)) 

Однако, вы получите сообщение об ошибке на этих выражений тоже, как :: не является членом класса Int (а также не член любого класса, для которого существует неявное преобразование).