将 Either 取消引用回到对象中
De-referencing Either back into the object
我正在尝试使用函数中的 Either return 类型来取回对象或字符串。如果它是一个对象,我想从这个对象开始调用方法。如果它是一个字符串,我想在别处调用一些其他函数。我总是被挂断,因为被 returned 的东西不是我正在 returning 的对象,它是 "left" 类型的,我似乎无法从中取出那个对象"Left" 类型变回我想要的 "Player" 类型。这包含在扩展可变队列的对象中。这是我的函数,它根据 ActionQueue 对象中的键在 Map 中查找 Player 对象:
def popCurrentAction : Either[Player, String] = {
val currentAction = this.dequeue
this.enqueue(currentAction)
if (playerMap.get(currentAction) != None) {
Left((playerMap.get(currentAction).get))
}
else {
Right(currentAction)
}
}
这是我的函数,它试图使用 returns "Player" 对象或字符串的函数。
def doMove = {
var currentAction = ActionQueue.popCurrentAction
if (currentAction.isLeft) {
var currentPlayer = currentAction.left
var playerDecision = currentPlayer.solicitDecision() // This doesn't work
println(playerDecision)
}
else {
// Do the stuff if what's returned is a string.
}
}
我试过使用 .fold 函数,它允许我调用 solicitDecision 函数并得到它 return 的内容,但我想直接使用 Player 对象。当然这是可能的。有人可以帮忙吗?
var currentPlayer = currentAction
var playerDecision = currentPlayer.fold(_.solicitDecision(), _.toString())
// This is close but doesn't give me the object I'm trying to get!
println(playerDecision)
你没有说明你遇到了什么错误,只是 "this doesn't work",而且你发布的代码不够完整,无法编译和测试。当编译器失败时 currentPlayer
类型是什么?
话虽如此,您可能会考虑重构您的代码。
def doMove = ActionQueue.popCurrentAction.fold(getDecision, stringStuff)
def getDecision(player: Player) = ....
def stringStuff(str: String) = ....
同时区分大小写和提取内容的最佳方法是使用模式匹配。
在您的情况下,大致是以下代码:
def doMove = {
val currentAction = ActionQueue.popCurrentAction
currentAction match {
case Left(currentPlayer) =>
val playerDecision = currentPlayer.solicitDecision()
println(playerDecision)
case Right(string) =>
println(string)
}
}
另请注意,我使用 val
而不是 var
。当你有一个你不打算改变的变量时,val
是更好的风格(粗略地说,它使一个只读变量)。
我正在尝试使用函数中的 Either return 类型来取回对象或字符串。如果它是一个对象,我想从这个对象开始调用方法。如果它是一个字符串,我想在别处调用一些其他函数。我总是被挂断,因为被 returned 的东西不是我正在 returning 的对象,它是 "left" 类型的,我似乎无法从中取出那个对象"Left" 类型变回我想要的 "Player" 类型。这包含在扩展可变队列的对象中。这是我的函数,它根据 ActionQueue 对象中的键在 Map 中查找 Player 对象:
def popCurrentAction : Either[Player, String] = {
val currentAction = this.dequeue
this.enqueue(currentAction)
if (playerMap.get(currentAction) != None) {
Left((playerMap.get(currentAction).get))
}
else {
Right(currentAction)
}
}
这是我的函数,它试图使用 returns "Player" 对象或字符串的函数。
def doMove = {
var currentAction = ActionQueue.popCurrentAction
if (currentAction.isLeft) {
var currentPlayer = currentAction.left
var playerDecision = currentPlayer.solicitDecision() // This doesn't work
println(playerDecision)
}
else {
// Do the stuff if what's returned is a string.
}
}
我试过使用 .fold 函数,它允许我调用 solicitDecision 函数并得到它 return 的内容,但我想直接使用 Player 对象。当然这是可能的。有人可以帮忙吗?
var currentPlayer = currentAction
var playerDecision = currentPlayer.fold(_.solicitDecision(), _.toString())
// This is close but doesn't give me the object I'm trying to get!
println(playerDecision)
你没有说明你遇到了什么错误,只是 "this doesn't work",而且你发布的代码不够完整,无法编译和测试。当编译器失败时 currentPlayer
类型是什么?
话虽如此,您可能会考虑重构您的代码。
def doMove = ActionQueue.popCurrentAction.fold(getDecision, stringStuff)
def getDecision(player: Player) = ....
def stringStuff(str: String) = ....
同时区分大小写和提取内容的最佳方法是使用模式匹配。
在您的情况下,大致是以下代码:
def doMove = {
val currentAction = ActionQueue.popCurrentAction
currentAction match {
case Left(currentPlayer) =>
val playerDecision = currentPlayer.solicitDecision()
println(playerDecision)
case Right(string) =>
println(string)
}
}
另请注意,我使用 val
而不是 var
。当你有一个你不打算改变的变量时,val
是更好的风格(粗略地说,它使一个只读变量)。