我开始学习静态类型的语言。动态后,只是切除大脑。我正在 GO 上编写一个 Web 服务器。我有 2 个函数(下面的示例),我可以在一个中声明一个结构并在另一个中使用吗?我的例子(它不起作用)
package main
import (
"fmt"
"encoding/json"
)
// эта функция неизменна и переиспользуется, поэтому я не могу объявлять структуру в ней
func getRequestData(Form type) {
/*
Здесь должен быть обработчик запроса. Он берёт json из запроса,
заносит данные в структуру и возвращает её, что-то типа:
*/
var form Form
jsonString := `{"username": "admin", "password": "1234"}`
json.Unmarshal([]byte(jsonString), &form)
return form
}
func main() {
type loginForm struct {
username string
password string
}
data := getRequestData(loginForm)
fmt.Println(data)
}
简短的回答:是的,你可以,但只能通过反思。
长答案。
Go 有两种处理值的机制——静态类型和反射。
该表达式
json.Unmarshal([]byte(jsonString), &form)使用反射。动态方法将Unmarshal提取表单变量的实际类型的描述,学习字段的名称、类型和相对于值开头的偏移量,并用反序列化的值填充它们。此方法不关心变量类型的确切声明位置form,因为该方法在动态中使用此类型。但!在它到达之前
Unmarshal,编译器必须处理函数调用getRequestData,并且你的代码被彻底破坏了。Go 中的类型名称不是对象标识符。
type参数描述中不能使用关键字。函数形参不能是类型,声明变量时不能用形参名作为类型名。您可以通过
interface{}. Go 中的这种类型代表任意类型此函数将从字符串中提取数据并将其存储在
map. 结构的 json 字段将可用作映射中的键:data["username"]和data["password"]然而,有趣
json.Unmarshal的是这个函数是完全动态类型的。她将检查参数结构中字段的组成,并尝试从 JSON 中正确恢复。您只需要传递一个指向预期结构的指针并检查返回的错误。
UPD。
回答原来的问题。由于它
json.Unmarshal通过反射处理值,因此该函数适用于在任何地方声明的任何类型。在我的回答中
LoginData移到了包级别(这是犹太教),但是可以在函数内部声明类型(尽管这不是正统的)。它会起作用的。主要是字段名要大写,否则不能通过反射改变,go会忽略。