GO Golang:匿名结构体和反射的结合

huangapple go评论81阅读模式
英文:

GO Golang : anonymous structs & Reflection combination

问题

在过去的两个月里,我已经阅读了关于反射的法则大约10次。在同样长的时间里进行开发,我必须说它是一种很酷且易于理解的语言...至少在某种程度上是这样。

作为PHP和JavaScript开发人员的背景使我很难理解以下示例:

package main

import(
	"fmt"
	"reflect"
)


func test1(){
	type template struct {
		Title string
		Body  string
	}
	
	data := []template{
		{ Title : "About page", Body : "Body info"},
		{ Body : "About page 2 ", Title : "Body info 2"},
	}

	fmt.Println( "-- TEST ONE --" ) 
	fmt.Println( data[0].Title )
}

func test2(){
	data := []struct{
		Title string
		Body  string
	}{
		// Assign with the actual order
		{ "About page", "Body info"},
		// Key => Val assignment (Pretty cool)
		{ Body : "Body info 2 ", Title : "About page 2"},
	}

	fmt.Println( "-- TEST TWO --" ) 
	fmt.Println( data[1].Title )
}

func test3(){
	type template struct {
		Title string
		Body  string
	}
	
	Amap := map[string]interface{}{
		"template" : template{},
	}
	
	w := reflect.ValueOf(Amap["template"])
	x := w.Type()
	y := reflect.TypeOf(w.Interface())
	z := reflect.TypeOf(Amap["template"])
	
	fmt.Printf("%+v\n", x) // main.template
	fmt.Printf("%+v\n", y) // main.template
	fmt.Printf("%+v\n", z) // main.template
	
	/*
	var data = struct{
		// none of the above can be place in here.... ( (w|x|y|z) is not a type)
	}{ "About page", "Body info";}
	*/

	ww := reflect.New(z)
	xx := ww.Interface()
	tt := reflect.TypeOf(xx)
	
	/*
	// none of the above can be used this way....
	var data = ww{
			
	}{ "About page", "Body info";}
	*/
	
	fmt.Println( "-- TEST THREE --" ) 
	fmt.Println( data.Title )
}

func main(){
	test1()
	test2()
	test3()
}

上述示例中的test1()test2()按预期工作。我想进一步尝试test3(),但没有成功。我能想到的唯一使其工作的方法是使用类型切换。

但由于我正在尝试一些东西,我想知道:

  1. 是否有一种方法可以在不对被反射的实际结构进行类型检查的情况下,将匿名结构从反射值转换为特定类型?
  2. 你能给我展示一个对test3()中两个被注释的代码块中的任意一个的有效解决方案吗?
英文:

After reading the laws of reflection about 10 times the last 2 months. Developing with it for the same amount of time, i have to say it is a cool and understandable language... at least to an certain level.

My background as PHP & Javascript developer are giving me an hard time to comprehend the following example:

package main
import(
"fmt"
"reflect"
)
func test1(){
type template struct {
Title string
Body  string
}
data := []template{
{ Title : "About page", Body : "Body info"},
{ Body : "About page 2 ", Title : "Body info 2"},
}
fmt.Println( "-- TEST ONE --" ) 
fmt.Println( data[0].Title )
}
func test2(){
data := []struct{
Title string
Body  string
}{
// Assign with the actual order
{ "About page", "Body info"},
// Key => Val assignment (Pretty cool)
{ Body : "Body info 2 ", Title : "About page 2"},
}
fmt.Println( "-- TEST TWO --" ) 
fmt.Println( data[1].Title )
}
func test3(){
type template struct {
Title string
Body  string
}
Amap := map[string]interface{}{
"template" : template{},
}
w := reflect.ValueOf(Amap["template"])
x := w.Type()
y := reflect.TypeOf(w.Interface())
z := reflect.TypeOf(Amap["template"])
fmt.Printf("%+v\n", x) // main.template
fmt.Printf("%+v\n", y) // main.template
fmt.Printf("%+v\n", z) // main.template
/*
var data = struct{
// none of the above can be place in here.... ( (w|x|y|z) is not a type)
}{ "About page", "Body info"}
*/
ww := reflect.New(z)
xx := ww.Interface()
tt := reflect.TypeOf(xx)
/*
// none of the above can be used this way....
var data = ww{
}{ "About page", "Body info"}
*/
fmt.Println( "-- TEST THREE --" ) 
fmt.Println( data.Title )
}
func main(){
test1()
test2()
test3()
}

The above example test1() and test2() work as expected. I wanted to push it even further with test3() but without success. The only way i could think of making it work was with an type switch..

But since I am trying things out I'd like to know if :

  1. Is there an way to cast an anonymous struct from an reflection value without type checking the actual struct that is being reflected
  2. Could you show me an working solution to either one of the 2 commented out code blocks from test3()

答案1

得分: 3

  1. 有没有一种方法可以在不对被反射的实际结构进行类型检查的情况下,从反射值中转换为一个匿名结构体?

  2. 在Go语言中没有类型转换。如果你指的是转换,那么你缺少一个条件:转换成什么类型?

  3. 类型检查是编译器对程序进行的操作。这个句子没有意义。

  4. 你能给我展示一下从test3()中两个被注释掉的代码块中的任意一个的工作解决方案吗?

很简单,只需要写:

var data = struct{string, string}{"About page", "Body info"}

如果你的意思是在运行时构建/创建/组装一个结构体类型,我必须让你失望;这是不可能的。

编辑(2015年2月11日):正在通过反射的方式实现在运行时构建结构体类型(以及数组、函数和接口)正在实施中

英文:

> 1. Is there a way to cast 1 an anonymous struct from an reflection value without type checking [2] the actual struct that is being reflected?

  1. There is no casting in Go. If you mean a conversion then you're missing a predicate: convert to what?
  2. Type checking is something a compiler does to a program. This sentence does not make sense.

> 2. Could you show me a working solution to either one of the 2 commented out code blocks from test3()

That's simple, just write:

var data = struct{string, string}{"About page", "Body info"}

If you mean to build/create/assemble a struct type on runtime I'll have to disappoint you; that's not possible.

Edit (11. Feb 2015): building struct types (as well as arrays, funcs and interfaces) on runtime by means of reflection is being implemented.

huangapple
  • 本文由 发表于 2014年11月21日 21:09:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/27062197.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定