#go #struct #dynamic #types #routes
#Вперед #struct #динамический #типы #маршруты
Вопрос:
Я новичок в go, на самом деле я хочу создать API с go, у которого есть динамический маршрут, как я сделал с Lumen, поэтому основная функция примерно такая :
func main() {
posts = append(posts, Post{ID: "1", Title: "My first post", Body: "This is the content of my first post"})
posts = append(posts, Post{ID: "2", Title: "My second post", Body: "This is the content of my second post"})
db, err = gorm.Open(dbclass.DbDriver, dbclass.DataSourceName)
if err != nil {
log.Println("Connection Failed to Open")
} else {
log.Println("Connection Established")
}
router := mux.NewRouter()
router.HandleFunc("/{model}", getAll).Methods("GET")
router.HandleFunc("/{model}", create).Methods("POST")
router.HandleFunc("/{model}/{id}", getById).Methods("GET")
router.HandleFunc("/{model}/{id}", update).Methods("PUT")
router.HandleFunc("/{model}/{id}", delete).Methods("DELETE")
http.ListenAndServe(":8000", router)
}
и я сохраняю файл модели mcustm.go в папке Models.
Поэтому, когда мы хотим получить всю любую модель, мы просто вызываем (пример в postman) что-то вроде этого :
localhost:8000/mcustm
это вызовет функцию GetAll, затем передаст mcustm
параметр в качестве имени модели, а функция GetAll — что-то вроде этого:
func getAll(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
vars := mux.Vars(r)
model = vars["model"] // the model slug
json.NewEncoder(w).Encode(model)
}
но это вообще не работает, потому что модель известна как String вместо struct Mcustm.
Я погуглил, чтобы решить эту проблему, и, возможно, нашел какое-то хорошее решение, используя этот подход:
package main
import (
"fmt"
"reflect"
)
var typeRegistry = make(map[string]reflect.Type)
func registerType(typedNil interface{}) {
t := reflect.TypeOf(typedNil).Elem()
typeRegistry[t.PkgPath() "." t.Name()] = t
}
type MyString string
type myString string
func init() {
registerType((*MyString)(nil))
registerType((*myString)(nil))
// ...
}
func makeInstance(name string) interface{} {
return reflect.New(typeRegistry[name]).Elem().Interface()
}
func main() {
for k := range typeRegistry {
fmt.Println(k)
}
fmt.Printf("%Tn", makeInstance("main.MyString"))
fmt.Printf("%Tn", makeInstance("main.myString"))
}
но все еще не решает мою проблему, потому что в функции init() мы должны вручную ввести для RegisterType структуру. Если у меня есть строка массива с именем структуры, как я могу динамически регистрировать тип, используя этот массив?
извините за мой плохой английский
Комментарии:
1. Пожалуйста, ознакомьтесь с Go для изучения основ языка, таких как пакеты и доступность.
2. спасибо за ваш ответ @mkopriva, я импортировал все необходимые пакеты, когда пробовал ту
mcustm = models.Mcustm
илиfmt.Println(reflect.TypeOf(mcustm))
иную результирующую модель. Mcustm это означает, что моя структура была доступна для чтения во время выполнения. Но я хочу, чтобы он был динамическим3. «Если у меня есть строка массива с именем структуры, как я могу динамически регистрировать тип, используя этот массив?» Вы не можете создавать типы из строки в Go, вам нужен реестр, и он должен иметь доступ к соответствующим типам Go, одних строк недостаточно. Единственный способ, который я могу придумать, позволяющий использовать только строки, — это использовать генератор кода, который принимает массив строк и создает реестр, однако это должно быть выполнено перед компиляцией.
4. GO не может генерировать типы динамически