使用 Scala trait 作为回调接口
Using Scala trait as a callback interface
我刚开始学习 scala,并尝试通过制作一个简单的应用程序 dicebot 来学习自己。
这是处理这个简单命令的简单应用程序。
CommandRouter().run("dice roll 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)
}
顺便说一句,在应用程序的第一部分,我想传递一个回调函数,它会在 Dice Bot 完成工作时被调用。
Dice.run(_command.tail, callback)
问题是..我不太确定要为 callback 参数传递什么。
如果这是 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 是接口,但我真的不明白。
trait BotInterface {
def onReceiveResult(result: List[String]): List[String]
}
请教一下如何使用trait作为回调接口?
提前致谢! :)
如果您需要的是一个接受 List[String]
并返回 List[String]
的回调,则不需要 trait,您可以要求一个 函数:
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
})
我们甚至可以使用 second 参数列表(这称为 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)
我刚开始学习 scala,并尝试通过制作一个简单的应用程序 dicebot 来学习自己。
这是处理这个简单命令的简单应用程序。
CommandRouter().run("dice roll 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)
}
顺便说一句,在应用程序的第一部分,我想传递一个回调函数,它会在 Dice Bot 完成工作时被调用。
Dice.run(_command.tail, callback)
问题是..我不太确定要为 callback 参数传递什么。 如果这是 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 是接口,但我真的不明白。
trait BotInterface {
def onReceiveResult(result: List[String]): List[String]
}
请教一下如何使用trait作为回调接口?
提前致谢! :)
如果您需要的是一个接受 List[String]
并返回 List[String]
的回调,则不需要 trait,您可以要求一个 函数:
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
})
我们甚至可以使用 second 参数列表(这称为 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)