2016-07-10 3 views
0

Я только начал изучать scala и пытаюсь научиться себе, сделав простое приложение, dicebot.Использование признака Scala в качестве интерфейса обратного вызова

Это простое приложение, которое обрабатывает эту простую команду.

CommandRouter(). Запуска ("бросок костей 3D4")

package com.kwoolytech.kwoolybot 

case class CommandRouter() { 

    def run(command: String): List[String] = { 
    val _command = command.split("\\s+").toList 

    commandArray.head match { 
     case "dice" => Dice.run(_command.tail) 
     case _ => List[] 
    } 
    } 
} 


package com.kwoolytech.kwoolybot 

case class Dice() extends Bot { 

    def run(command: List[String]): List[String] = { 
    command.head match { 
     case "roll" => roll(_command.tail) 
     case _ => List[] 
    } 
    } 

    private def roll(command: Array[String]): List[String] = { 
    val rollCmdPattern = "([0-9]+)d([0-9]+)".r 

    command.head match { 
     case rollCmdPattern(numTry, diceSize) => rollDice(numTry, diceSize) 
     case _ => List[] 
    } 
    } 

    private def rollDice(numTry: Int, diceSize: Int): List[String] = { 
    (1 to numTry).map { x => scala.util.Random.nextInt(diceSize) + 1}) 
    }.toList.map(_.toString) 

} 

BTW, в самой первой части приложения, я хочу передать через функцию обратного вызова, которая будет получать когда Dice Bot выполнил свою работу.

Dice.run (_command.tail, обратного вызова)

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

interface KwoolyHttpCallback { 
    void onWeatherJsonDataReceived(String result); 
    void onWeatherBitmapDataReceived(Bitmap result); 
} 

private void initializeKwoolyHttpCallbackFunction() { 
httpClientCallback = new KwoolyHttpCallback() { 
    @Override 
    public void onWeatherJsonDataReceived(String result) { 
     try { 
      dataModel.setWeatherJsonData(result); 
      queryWeatherBitmapData(); 
     } catch (Exception e) { 
      Log.e(getClass().getName(), "Exception: "); 
      e.printStackTrace(); 
     } 
    } 

Я где-то слышал, что черта - это интерфейс, но я действительно не понимаю.

trait BotInterface { 
    def onReceiveResult(result: List[String]): List[String] 
} 

Не могли бы вы научить меня, как использовать эту черту в качестве интерфейса обратного вызова?

Заранее благодарен! :)

ответ

1

Если то, что вам нужно, это обратный вызов принимает List[String] и возвращение List[String], нет никакой необходимости в признаке, вы можете потребовать функции:

def run(command: List[String], callback: List[String] => List[String]): List[String] 

callback использует маленький синтаксический сахар для определения. Он фактически переводится в тип с именем Function1[List[String], List[String]].

Теперь абоненты могут использовать анонимный синтаксис функции для передачи в реализации:

run(List("1","2","3"), l => { 
    l.foreach(println) 
    l 
}) 

Мы можем даже сделать это немного симпатичнее, используя второй список из параметров (это называется currying):

def run(command: List[String])(callback: List[String] => List[String]): List[String] 

И теперь мы имеем:

run(List("1","2","3")) { l => 
    l.foreach(println) 
    l 
} 

Если вы по-прежнему убеждены в том, что вы хотите trait, на самом деле это очень похоже на то, как вы бы определить интерфейс в Java:

trait BotInterface { 
    def onReceiveResult(result: List[String]): List[String] 
} 

def run(command: List[String], callback: BotInterface): List[String] 

Обратите внимание, что качество в Scala могут иметь реализацию по умолчанию, аналогичный методы по умолчанию Java 8 в:

trait BotInterface { 
    def onReceiveResult(result: List[String]): List[String] = result.map(_.toLowerCase) 
} 

А внутри run определения вам необходимо позвонить callback.onReceiveResult(list)

+1

Эй, Юваль, я ценю за вашу помощь. Думаю, я понял. благодаря! – Harry

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