英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论