我想知道表达类似消息(值对象)的惯用方法是什么 我们假设我要发送一些消息:UserEnter,UserLeft,UserSendGreeting等'。我希望以下内容可以表达我的困境
我认为有两个选项可以表达它:
trait UserAction
case class UserEnter (username:String,hour:Long,day:WeekDay,room:Int)
case class UserLeft (username:String,hour:Long,day:WeekDay,room:Int)
case class UserSendGreeting (username:String,,hour:Long,day:WeekDay,greeting:String)
def foo(userActions:List[UserAction]) = {
userActions match {
case UserEnter(userName)::tail =>
sendWelcomeMessage(userName)
handleOtherActions(tail)
case UserLeft::tail => "must enter first"
case _ => "do something else"
}
另一种方式是:
trait Action
case class Enter(room:Int) extends Action
case object Left(room:Int) extends Action
case object Greet(msg:String) extends Action
case class UserAction(username:String,action:Action,,hour:Long,day:WeekDay)
def foo(userActions:List[UserAction]) = {
userActions match {
case head::tail if head.action == Enter =>
sendWelcomeMessage(head.userName)
handleOtherActions(tail)
case head::tail if head.action == Left => "must enter first"
case _ => "do something else"
}
第一个选项更明确,更容易进行模式匹配,但更重复的代码。 另一个对动作本身更明确,但模式匹配更详细 哪种方式更好?
答案 0 :(得分:3)
User
(在您的案例中为字符串名称)和Action
,请使用Tuple
。收集所有" ...其他属性"也是有意义的。在相应的Action
内。
type User = String
sealed trait Action
case class Enter(room:Int) extends Action
case class Left(room:Int) extends Action
case class Greet(msg:String) extends Action
def foo(userActions:List[(User, Action)]) = userActions match {
case (username, _:Enter)::tail =>
sendWelcomeMessage(username)
handleOtherActions(tail)
case (username, _:Left)::tail => "must enter first"
case _ => "do something else"
}
另外请不要忘记,模式匹配允许您unapply
任意深度的层次结构:
case (username, Enter(room))::tail =>
答案 1 :(得分:0)
我认为1种方法更好,但您可以对UserAction特性进行约束以获得用户名字段:
trait UserAction {
def username: String
}
case class UserEnter(username:String, room:Int)
case class UserLeft(username:String, room:Int)
case class UserSendGreeting(username:String, greeting:String)
这种方式很容易
1)模式匹配
2)使用通用UserAction
获取用户名字段
答案 2 :(得分:0)
如何:TABLES: VBRK.
DATA: BEGIN OF it_test,
BUKRS(5), "longer version of VBRK-BUKRS,
FKDAT LIKE VBRK-FKDAT,
END OF it_test.
DATA: tt_test TYPE STANDARD TABLE OF it_test.
* I would strongly recommend to set a filter!
SELECT * FROM VBRK INTO CORRESPONDING FIELD OF it_test.
IF it_test-BUKRS = 'xxxx'.
it_test-BUKRS = 'XXXXX'.
APPEND it_test to tt_test.
ENDIF.
ENDSELECT.
case class UserAction(user: User, action: Action)
甚至更好
def foo(actions: Seq[UserActions]) = actions match {
case UserAction(user, _: EnterAction)::tail =>
processEnter(user)
handleOtherActions(tail)
case UserExit(user, _: ExitAction)::tail => processExit(user)
...
}
或者,也许,只是
def foo(actions: Seq[UserAction]) = actions.find { ua =>
!ua.action.process(ua.user)
}