Go语言中能否在同一条语句中为普通变量赋值并操作切片索引?
Go语言批量类型断言并记录结果的实现方案
你想要的在同一条var语句中同时为普通变量和切片索引赋值的写法,在Go语法里是无法实现的——因为var声明块的左操作数只能是标识符(变量名),而asserts[0]这类切片索引属于表达式,不符合语法要求,这就是你看到语法错误的原因。
不过可以通过以下两种替代方案实现你的需求:
方案一:拆分声明与赋值,使用普通赋值语句记录断言结果
先单独声明所有需要的变量,再用普通赋值语句完成类型断言,同时将断言结果存入切片对应索引:
// inside a function: // 初始化断言结果切片,长度设为需要断言的次数(这里是5次) asserts := make([]bool, 5) 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 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) assertionHandler(&asserts)
普通赋值语句允许左操作数使用切片索引表达式,因此可以正常完成赋值和结果记录。
方案二:封装工具函数自动记录断言结果
如果不想手动管理切片索引,可以封装一个泛型函数,自动将断言结果追加到切片中:
// inside a function: asserts := make([]bool, 0, 5) 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) } // 封装泛型函数,自动记录断言结果到切片 func assertAndRecord[T any](v any, asserts *[]bool) (T, bool) { res, ok := v.(T) *asserts = append(*asserts, ok) return res, ok } var ( possibleSquares []string dataObject map[string]any playerData map[string]any square string piece string color string ) // 使用工具函数完成断言,无需手动指定索引 dataObject, _ = assertAndRecord[map[string]any](data, &asserts) playerData, _ = assertAndRecord[map[string]any](dataObject["playerData"], &asserts) square, _ = assertAndRecord[string](playerData["selectedPieceLocation"], &asserts) piece, _ = assertAndRecord[string](playerData["selectedPiece"], &asserts) color, _ = assertAndRecord[string](playerData["selectedPieceColor"], &asserts) assertionHandler(&asserts)
这种方式不需要手动维护索引,避免了索引写错的风险,代码也更简洁。
内容的提问来源于stack exchange,提问作者marcosdly
相关产品推荐
相关产品推荐

