2015-02-15 4 views
1

Во-первых, это больше для экспериментов и обучения на этом этапе, и я знаю, что могу просто передать параметр непосредственно.Как использовать неявное во время выполнения?

def eval(xs: List[Int], message: => String) = { 
    xs.foreach{x=> 
    implicit val z = x 
    println(message) 
    } 
} 

def test()(implicit x : Int) = { 
    if(x == 1) "1" else "2" 
} 

eval(List(1, 2), test)//error: could not find implicit value for parameter x 

Возможно ли это, и я просто не использую implicits правильно для ситуации? Или это вообще невозможно?

ответ

3

неявных параметров во время компиляции. Параметр By-name фиксирует значения, которые он обращается в области, в которой он передан.

Во время выполнения не существует какой-либо неявной концепции.

eval(List(1, 2), test) 

Это должно быть полностью разрешено во время компиляции. Компилятор Scala должен выяснить все параметры, необходимые для вызова test. Он попытается найти неявную переменную Int в области , где eval называется. В вашем случае неявное значение, определенное в eval, не будет иметь никакого эффекта во время выполнения.

0

Я предполагаю, что вы хотите неявный параметр x (в подписи test «s) должны быть заполнены неявной переменной zeval). В этом случае z не входит в объем, в пределах которого x может видеть z. Неявное разрешение статически выполняется компилятором, поэтому поток данных во время выполнения никогда не влияет на него. Чтобы узнать больше о области, полезно Where do Implicits Come From? в this answer.

Но для этой цели вы можете использовать implicit. (Я думаю, что это злоупотребление implicit так только для демонстрации.)

var z = 0 
implicit def zz: Int = z 

def eval(xs: List[Int], message: => String) = { 
    xs.foreach{ x => 
    z = x 
    println(message) 
    } 
} 

def test()(implicit x : Int) = { 
    if(x == 1) "1" else "2" 
} 

eval(List(1, 2), test) 
1

Как получить неявное значение всегда разрешается во время компиляции. Нет такой вещи, как объект Function с неявным параметром. Чтобы получить вызываемый объект из метода с неявными параметрами, вам нужно сделать его явным. Если вы действительно хотите, вы можете затем обернуть, что в другом методе, который использует implicits:

def eval(xs: List[Int], message: Int => String) = { 
    def msg(implicit x: Int) = message(x) 
    xs.foreach { x => 
    implicit val z = x 
    println(msg) 
    } 
} 

eval(List(1, 2), test()(_)) 

Вы, вероятно, не будет ничего получить, делая это.

Implicits не является альтернативой для передачи параметров. Они являются альтернативой явным написанием параметров, которые вы проходите. Однако фактическое прохождение работает одинаково.

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