英文:
Is it possible to assign to a regular variable and slice in the same statement?
问题
我正在制作一个国际象棋游戏,我想在同一个var语句中进行一系列的类型断言,然后将它们传递给一个处理函数,但显然,Go语言不允许我在同一个语句中给普通变量和切片索引赋值:
// 在一个函数内部:
asserts := make([]bool, 0, 10)
assertionHandler := func(ok *[]bool) {
for _, b := range *ok {
if !b {
msg := "pieceCliked: 在尝试进行类型断言时失败\n%s\n\n"
utils.LogPrintError(errors.New(fmt.Sprintf(msg, string(debug.Stack()))))
}
}
*ok = make([]bool, 0, 10)
}
var (
possibleSquares []string
// 下面的代码会导致语法错误:期望类型,但找到了'='
dataObject, asserts[0] = data.(map[string]interface{})
playerData, asserts[1] = dataObject["playerData"].(map[string]interface{})
square, asserts[2] = playerData["selectedPieceLocation"].(string)
piece, asserts[3] = playerData["selectedPiece"].(string)
color, asserts[4] = playerData["selectedPieceColor"].(string)
)
assertionHandler(asserts)
我尝试做的事情是可行的吗?
英文:
I'm making a chess game and I want to do a series of type assertions in the same var statement, then pass them to a function that handles it, but apparently, Go doesn't allow me to assign to a regular variable and a slice index in the same statement:
// inside a function:
asserts := make([]bool, 0, 10)
assertionHandler := func(ok *[]bool) {
for _, b := range *ok {
if !b {
msg := "pieceCliked: failed while trying to do type assertion\n%s\n\n"
utils.LogPrintError(errors.New(fmt.Sprintf(msg, string(debug.Stack()))))
}
}
*ok = make([]bool, 0, 10)
}
var (
possibleSquares []string
// The following results in a syntax error: expected type, found '='
dataObject, asserts[0] = data.(map[string]any)
playerData, asserts[1] = dataObject["playerData"].(map[string]any)
square, asserts[2] = playerData["selectedPieceLocation"].(string)
piece, asserts[3] = playerData["selectedPiece"].(string)
color, asserts[4] = playerData["selectedPieceColor"].(string)
)
assertionHandler(asserts)
Is it possible to do what I'm trying to do?
答案1
得分: 2
你这样做是不对的。var 块用于定义新的变量及其类型,但你试图在没有类型的情况下给新变量和现有切片中的元素赋值,所以出现了错误 expected type。
你可以这样做:
var (
possibleSquares []string
dataObject map[string]interface{}
playerData map[string]interface{}
square string
piece string
color string
)
dataObject, asserts[0] = data.(map[string]interface{})
playerData, asserts[1] = dataObject["playerData"].(map[string]interface{})
square, asserts[2] = playerData["selectedPieceLocation"].(string)
piece, asserts[3] = playerData["selectedPiece"].(string)
color, asserts[4] = playerData["selectedPieceColor"].(string)
注意,我将 any 类型更改为了 interface{} 类型,因为 Go 语言中没有 any 类型。
英文:
Not the way you're doing it, no. A var block defines new variables and their types, but you're trying to assign to both new variables with no types (hence the error expected type) and elements of an existing slice within that block.
You could do:
var (
possibleSquares []string
dataObject map[string]any
playerData map[string]any
square string
piece string
color string
)
dataObject, asserts[0] = data.(map[string]any)
playerData, asserts[1] = dataObject["playerData"].(map[string]any)
square, asserts[2] = playerData["selectedPieceLocation"].(string)
piece, asserts[3] = playerData["selectedPiece"].(string)
color, asserts[4] = playerData["selectedPieceColor"].(string)
答案2
得分: 1
另一个答案描述了为什么问题中的代码不起作用。这里是另一种解决方法:
编写断言处理程序来使用可变参数:
func assertionHandler(asserts ...bool) bool {
result := true
for _, b := range asserts {
if !b {
result = false
msg := "pieceCliked: 在尝试进行类型断言时失败\n%s\n\n"
utils.LogPrintError(errors.New(fmt.Sprintf(msg, string(debug.Stack()))))
}
}
return result
}
使用短变量声明来收集值和布尔结果:
dataObject, assert0 := data.(map[string]interface{})
playerData, assert1 := dataObject["playerData"].(map[string]interface{})
square, assert2 := playerData["selectedPieceLocation"].(string)
piece, assert3 := playerData["selectedPiece"].(string)
color, assert4 := playerData["selectedPieceColor"].(string)
if !assertionHandler(assert0, assert1, assert2, assert3, assert4) {
return
}
请注意,我已经将 any 类型更改为 interface{} 类型,因为 Go 语言中没有 any 类型。
英文:
Another answer describes why the code in the question does not work. Here's another workaround:
Write assertion handler to use variadic argument:
func assertionHandler(asserts ...bool) bool {
result := true
for _, b := range assserts {
if !b {
result = false
msg := "pieceCliked: failed while trying to do type assertion\n%s\n\n"
utils.LogPrintError(errors.New(fmt.Sprintf(msg, string(debug.Stack()))))
}
}
return result
}
Use short variable declarations to collect the values and bool results:
dataObject, assert0 := data.(map[string]any)
playerData, assert1 := dataObject["playerData"].(map[string]any)
square, assert2 := playerData["selectedPieceLocation"].(string)
piece, assert3 := playerData["selectedPiece"].(string)
color, assert4 := playerData["selectedPieceColor"].(string)
if !assertionHandler(assert0, assert1, assert2, assert3, assert4) {
return
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论