2015-03-11 2 views
1

УчитываяКак динамически привязать ссылку метода к признаку?

def add(x: Int, y: Int): Int = x + y 

val addAsMethodReference: (Int, Int) => Int = add _ 

trait BinaryOperator { 
    def execute(x: Int, y: Int): Int 
} 

val addAsBinaryOperator: BinaryOperator = addAsMethodReference...? 

Как я связываю addAsMethodReference к BinaryOperatorбез реализации BinaryOperator вручную?

Java 8 SAM будет работать. Я мог бы использовать ссылку метода в любом месте бинарного оператора черт используется в Java 8.

В идеале, я хочу написать что-то вроде:

var addAsBinaryOperator: BinaryOperator = addAsMethodReference.asNewInstanceOf[BinaryOperator] 

Причины Я хочу это asNewInstanceOf метода он будет работать для любого метода подпись. Мне все равно, сколько параметров передается. Если бы мне пришлось реализовать это вручную, я должен тщательно сопоставить каждый x и y. Это склонность к ошибкам в большем масштабе.

Спецификация left.asNewInstanceOf[right] будет, если сторона right имеет более одного абстрактного метода, она не работает при компиляции. Если сторона left не является функциональным типом, который соответствует единственной абстрактной сигнатуре метода на стороне right, это не сработает при компиляции. Сторона right не обязательно должна быть чертой, она может быть абстрактным классом с единственным абстрактным методом.

+0

Не могли бы вы высказать какой-то код того, что вы хотели бы написать? – ale64bit

+0

Ммм ..... тогда я думаю, что тебе нужна магия. – ale64bit

+0

Это нормально сказать, что это невозможно в Скале. – Pyrolistical

ответ

0

NEW ANSWER:

Это делает то, что вы хотите. Он динамически создает BinaryOperator объект, execute метод связан с addAsMethodReference:

def add(x: Int, y: Int): Int = x + y 

val addAsMethodReference: (Int, Int) => Int = add _ 

trait BinaryOperator { 
    def execute(x: Int, y: Int): Int 
} 

val addAsBinaryOperator: BinaryOperator = 
    new BinaryOperator{ def execute(x: Int, y: Int): Int = addAsMethodReference(x,y) } 

OLD ОТВЕТ

Является ли это то, что вы хотите?

implicit class EnhancedBinaryOperator(val self: BinaryOperator) extends AnyVal { 
    def addAsMethodReference(a: Int, b: Int) = a + b 
} 

val o: BinaryOperator = ??? // anything here 
o.addAsMethodReference(1,2) // addAsMethodReference is now on BinaryOperator 
+0

это просто странный способ его реализации вручную – Pyrolistical

+1

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

+0

@Pyrolistical Это обычный шаблон для добавления методов к классам/объектам/объектам, к которым у вас нет доступа (например, из стандартной языковой библиотеки). – ale64bit

2

Ну, вы могли бы сделать неявный

implicit def myConversion(f: (Int, Int) ⇒ Int): BinaryOperator = new BinaryOperator { 
    def execute(x: Int, y: Int): Int = f(x, y) 
    } 

и если он находится в области видимости, вы можете просто сделать

val addAsBinaryOperator: BinaryOperator = addAsMethodReference 

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

+0

Это ближе, чем другой ответ. Но вы по-прежнему вручную используете переменные x и y. – Pyrolistical

+0

Я не уверен, как вы ожидаете, что метод узнает, что он должен связываться с 'execute', если вы не сообщите об этом. Это так же хорошо, как и получается ... ну, по крайней мере, до версии 2.13, когда становится доступной библиотека 'mind-reading'. – dhg

+0

@Pyrolistical Единственная альтернатива этому, о которой я могу думать, делает некоторые макросы. Тем не менее, это уже дальше, чем я хотел бы воспользоваться этой возможностью. Как упоминалось в @dhg, до тех пор, пока 'mind-reading' не будет выпущен, вы не сможете заставить компилятор делать такие вещи. Возможно, вы можете сделать те черты, которые вы хотите назначить методам, более гибкие или более контролируемые, таким образом, чтобы вы могли обеспечить эту функциональность. – ale64bit