【发布时间】:2021-06-16 18:30:51
【问题描述】:
给定这样的方法:
def toFun()(implicit a: Box) = a.toCircle()
据我了解,目前我们需要这样的语法:
anObject match {
case Another(a,b,c, _) =>
implicit val tempA = a
toFun()
case YetAnother(a,b,_) =>
implicit val tempA = a
toFun()
}
我们有更直观的语法吗?
anObject match {
case Another(implicit a,b,c, _) =>
toFun()
case YetAnother(implicit a,b,_) =>
toFun()
}
更新:
我知道我们可以这样做:
anObject match {
case Another(a,b,c, _) =>
toFun()(a)
case YetAnother(a,b,_) =>
toFun()(a)
}
但如果是这样的方法:
def toFun()(implicit a: Box, b: Size, c: Context) = a.toCircle()
将需要执行以下操作,从而违背了隐含的目的:
def main = {
implicit context =>
anObject match {
case Another(a,b,c, _) =>
toFun()(a,b, context)
case YetAnother(a,b,_) =>
toFun()(a,b,context)
}
}
示例:
请注意messageContext 及其用法
class Worker extends Actor {
def receive = {
case m: MessageContext =>
/**
*
* Notice this
*/
implicit val messageContext = m
processor.processMessage{
conversation =>
val lastMessage = conversation.chat.last
lastMessage.message match {
case Some(text) =>
if (text.contains("/search")) {
val searchArgs = text.trim.split("/search")
if (searchArgs.nonEmpty) {
val query = searchArgs.last.trim
system.scheduler.scheduleOnce(1800 milliseconds) {
val activeContent = s"""
Some content"
|""".stripMargin)
conversation.activeContent = activeContent
processor.reply(s"""
|Here are search results for "${query}":
|${activeContent.mkString("\n------------\n")}
|
|""".stripMargin)
}
s"""Hello ${conversation.user.firstName}, we have received a search query for "${query}". We will soon respond with search results"""
} else {
s"""Hello ${conversation.user.firstName}, please enter a keyword post search command, i.e. "/search keyword"!"""
}
} else if (text.contains("/remind")) {
if (conversation.activeContent.isEmpty) {
"Please /search something first"
} else {
val remindArgs = (allCatch opt(text.split("/remind").last.trim.toInt)) // .split(" ")
if (remindArgs.isDefined) {
system.scheduler.scheduleOnce(5000 milliseconds) {
/**
*
* The above implicit is used here, if I pass it as an argument, then I will needed to pass other implciit arguments as well
* If I pass message as a standard argument, then the reply method looses it's simplciity, and please do factor in that
* we will need to call it at n number of times as the conversation tree grows
*/
processor.reply(s"""Here's the reminder after 5 seconds for resource: ${conversation.activeContent(remindArgs.get - 1)}""")
}
s"Hello ${conversation.user.firstName}, we would love to remind you about the resource: ${conversation.activeContent(remindArgs.get - 1)} "
} else {
"""Please enter valid index number, refer to search results. Use the number in begining of each search result item i.e. "/remind 1" or "/remind 2" or "/remind 5"!"""
}
}
} else {
conversation.activeTopic match {
case Some(topic)=>
topic match {
case Goal =>
"Some message..."
case ChangeTopic =>
if (List("yes", "yeah", "yo", "yay", "y", "ya", "yepp", "why not").contains(text.toLowerCase.replace("!", ""))) {
system.scheduler.scheduleOnce(5000 milliseconds) {
/**
*
* Notice this
*
*/
processor.reply(s"""Yeah, we can change the topic""")
}
"Let me think if we are done here"
}
else {
"Some message..."
}
case .......
}
case _ => s"No active topic out there! Would you like to /start again?"
}
}
case None =>
conversation.activeTopic match {
case Some(topic)=>
topic match {
case GoalUploadPrompt =>
lastMessage.raw.document match {
case Some(doc) => doc.toString
case None => lastMessage.raw.photo match {
case Some(photo) =>
"Some message..."
case None => "Some message..."
}
}
case _ =>
"Some message..."
}
case None => "Some message...."
}
}
}(m, ws, token)
case _ =>
}
}
object processor {
def processMessage(cb: (BotConversation) => String)(implicit msg: MessageContext, ws: WSClient, token: String) = ?
}
【问题讨论】:
-
也可以显式传递隐式参数:
toFun()(a) -
是的,我知道一个,它在很多情况下会导致另一个问题,请查看更新。
-
什么“另一个问题”?
-
@Dima 请看更新
-
@OldGaurd01 简短的回答是您使用的隐含错误。如果您必须从某处提取值以在调用站点指定它们,那么它们首先不应该是隐含的。因此,这里的“正确”解决方案是将这些参数明确化。它会立即解决您提到的所有问题。除此之外,您将必须命名您“手动”传递的值,我真的看不出您的变体中有任何优于向您建议的选项。