我有2种变量。检查Go游乐场,我不明白为什么会这样。问题:我从中得到的Models
应该是struct
将其用于GORM
First()
功能。
代码:
package main
import (
"fmt"
)
type Test struct {
Test string
}
var Models = map[string]interface{}{
"test": newTest(),
}
func main() {
test1 := Test{}
fmt.Println("Test 1: ")
fmt.Printf("%v", test1)
fmt.Println()
fmt.Println("Test 1 as pointer: ")
fmt.Printf("%v", &test1)
fmt.Println()
test2 := Models["test"]
fmt.Println("Test 2: ")
fmt.Printf("%v", test2)
fmt.Println()
fmt.Println("Test 2 as pointer: ")
fmt.Printf("%v", &test2)
}
func newTest() Test {
var model Test
return model
}
TL; DR:
在第一种情况下,您传递了*Test
用于打印的type值,但在第二种情况下,您传递了type的值*interface{}
!该%v
动词表示使用默认格式进行格式化,但是默认格式取决于值的类型。
您看到的区别只是fmt
包实现的默认格式设置规则。
您正在使用fmt.Printf()
:
func Printf(format string, a ...interface{}) (n int, err error)
它以格式字符串和其他参数作为类型interface{}
。因此请注意,如果您传递的值不是type
interface{}
,则该值将被包装为type值interface{}
。
现在,让我们看看您的示例:
test1 := Test{}
// ...
fmt.Printf("%v", &test1)
test1
是类型的Test
,而您通过的&test1
是类型*Test
。这将包装在interface{}
。来自的打包文档的格式规则fmt
:
对于复合对象,将使用以下规则递归地打印元素,其布局如下:
struct: {field0 field1 ...} array, slice: [elem0 elem1 ...] maps: map[key1:value1 key2:value2] pointer to above: &{}, &[], &map[]
由于它是指向的指针struct
,因此&{}
将使用该格式。Test
有一个字段Test string
,但是您没有设置它的值,因此它默认为空字符串类型的零值。这就是为什么在显示时什么也看不到的原因。请注意,如果您要像这样初始化它:string``""
test1 := Test{"a"}
输出为:
&{a}
让我们来看第二个例子:
test2 := Models["test"]
// ...
fmt.Printf("%v", &test2)
第一行是一个简短的变量声明,类型test2
将从右侧表达式中推断出来。右侧表达式是一个索引表达式,为地图建立索引。其类型将是映射的值类型,并且由于类型为Models
is
map[string]interface{}
,所以类型of test2
将为interface{}
。
到目前为止,一切都很好。但是,当您尝试像这样打印时会发生什么fmt.Printf("%v", &test2)
?您传递的指针test2
类型是interface{}
,所以传递的类型是*interface{}
,并且由于与并不相同interface{}
,它将被包装在另一个interface{}
值中。
因此,传递给它的fmt.Printf()
是一个interface{}
值,将*interface{}
值包装为test2
变量的地址。
现在,此处适用的格式设置规则:
%v的默认格式为:
bool: %t int, int8 etc.: %d uint, uint8 etc.: %d, %x if printed with %#v float32, complex64, etc: %g string: %s chan: %p pointer: %p
由于要格式化的值是指针(*interface{}
),%v
因此默认为%p
,即:
指针:
%p base 16 notation, with leading 0x
因此,结果是正确以十六进制格式打印地址值,例如:
0x1040a160
要从中获取结构test2
,可以使用类型断言。因此它应该是这样的:
t2 := Models["test"]
test2 := t2.(Test) // test2 is of type Test
该test2
类型与的类型相同test1
,并且在打印时将产生相同的结果。在Go
Playground上尝试一下。
最好是将*Test
值存储在映射中,因此不需要类型声明,甚至不需要存储在局部变量中,因为interface{}
映射中存储的对象已经是的指针Test
,可以按原样使用/传递它。
本文向大家介绍数组和指针之间的区别,包括了数组和指针之间的区别的使用技巧和注意事项,需要的朋友参考一下 在本文中,我们将了解数组和指针之间的区别。 数组 它存储具有同类数据类型的变量的值。 它可以生成一个指针数组。 它支持数组的概念。 可以生成一个指针数组。 它指的是由相同/相同数据类型的元素组成的集合。 它使用下标/'[]'(方括号)来访问元素。 它是指向集合的第一个元素的指针。 数组对象无法实
问题内容: 我目前正在学习使用Go语言编程。我在理解Go指针时遇到了一些困难(并且我的C / C ++现在很遥远…)。例如,在“第52号游览”中(http://tour.golang.org/#52),我读到: 但是如果不是 我写: 甚至: 反之亦然: 我得到了完全相同的结果。有区别吗(在内存方面,等等)? 问题答案: 您的示例使用两种Go语言规则: 可以从具有值接收器的方法派生具有指针接收器的方
本文向大家介绍golang方法中receiver为指针与不为指针的区别详析,包括了golang方法中receiver为指针与不为指针的区别详析的使用技巧和注意事项,需要的朋友参考一下 前言 golang的指针receiver和非指针receiver的区别?最近在看网站有同学提问golang中方法的receiver为指针和不为指针有什么区别,在这里我以简单易懂的方法进行说明,帮助刚刚学习golang
值得注意点的是切片的本质就是一个指针指向数组,所以指向切片的指针是一个二级指针 package main import "fmt" func main() { // 1.定义一个切片 var sce[]int = []int{1, 3, 5} // 2.打印切片的地址 // 切片变量中保存的地址, 也就是指向的那个数组的地址 sce = 0xc0420620a0 f
和 C 语言一样,允许用一个变量来存放其它变量的地址,这种专门用于存储其它变量地址的变量,我们称之为指针变量 和 C 语言一样,Go 语言中的指针无论是什么类型占用内存都一样(32位4个字节,64位8个字节) package main import ( "fmt" "unsafe" ) func main() { var p1 *int; var p2 *floa
与普通指针并无差异 package main import "fmt" func main() { var dict map[string]string = map[string]string{"name":"lnj", "age":"33"} var p *map[string]string = &dict (*p)["name"] = "zs" fmt.Println(di