2016-08-14 3 views
2

Я написал этот примерПонимание неявный <: <параметр

class TestMatch[T](private val t: T){ 
    def test()(implicit ev: T <:< Option[Int]) = println(ev(t).get) 
} 

и испытание для его

val tm = TestMatch(Some(10)) 
tm.test() //fine 

val tm2 = TestMatch(10) 
tm2.test() //compilation error 

Вопрос заключается в том, кто создает implicit ev: T <:< Option[Int], когда я взываю test метод? Я знаю, что нет. Может быть, компилятор знает о implicit <:< и знает, что с ним делать.

Documenation из <:< не совсем ясно

Чтобы ограничить любой абстрактный тип T, который находится в области видимости, в списке аргумента метода (а не только собственные параметры типа метода в) просто добавить неявный аргумент типаT <:< U, где U - обязательная верхняя граница ; или для нижних границ, используйте: L <:< T, где L - это требуемая нижняя граница.

Означает ли это, что компилятор возьмет остальные на себя? Я просто добавляю implicit ev: T1 <:< T2?

+0

На основе последних вопросов, которые вы разместили у вас, кажется, есть некоторые вопиющие пробелы в своих знаниях о Scala. Я бы посоветовал вам прочитать хорошую книгу о языке Scala и программировании Scala. –

ответ

2

Первый фрагмент компилирует из Predef.identity, что означает, что вы всегда можете неявно преобразовать тип T к типу T (в данном случае Option[Int]). В противном случае вам нужно будет ввести косвенно в scopre самостоятельно.

1

Означает ли это, что компилятор возьмет остальное на себя?

Компилятор будет искать скрытую область видимости. Если он найдет совпадение, он предоставит его, если он не сможет, вы получите ошибку компиляции. В вашем примере компилятор обнаружил, что Some[Int] придерживается неявного требования Some[Int] <:< Option[Int], поскольку он является прямым подтипом Option[Int].

Вы можете увидеть это при компиляции коды с scalac:

val tm: TestMatch[Some[Int]] = new TestMatch[Some[Int]](scala.Some.apply[Int](10)); 
tm.test()(scala.this.Predef.$conforms[Some[Int]]); 

Где для Int (вашего второго примера), не подразумевается в объеме, соответствующие требования, и Int не является подтип Option[Int].

+1

Любая идея, почему добавление такого рода вещей не работает? 'implicit def nonZeroInt (i: Int): Option [Int] = if (i == 0) None else Some (i)' (я добавил на том же уровне, что и вызов 'test') – Dici

1

Компилятор попытается найти неявные параметры в различных предопределенных местах. Если он не сможет найти их, это вызовет ошибку. Эта ссылка может помочь: http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

enter image description here

+0

Это в значительной степени ссылка -он ответ – Dici

+0

Хорошо, я мог бы удалить его, если хотите.Я думал, что будет легче увидеть все места, которые компилятор ищет неявным с помощью этого изображения, вместо того, чтобы вводить их. – Samar

+0

Я думаю, что ссылка полезна, но вы должны попытаться добавить к ней какое-то значение. Не удаляйте свой ответ только для меня: p – Dici

Смежные вопросы