在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
如果给这个类型增加或者删除某个值,是要创建一个新值,还是要更改当前的值? 如果是要创建一个新值,该类型的方法就使用值接收者。 如果是要修改当前值,就使用指针接收者。 这个答案也会影响程序内部传递这个类型的值的方式:是按值做传递,还是按指针做传递。 保持传递的一致性很重要。
一、内置类型 字符串(string)就像整数、浮点数和布尔值一样,本质上是一种很原始的数据值,所以在函数或方法内外传递时,要传递字符串的一份副本。
二、引用类型 切片、映射、通道、接口和函数类型等。当声明上述类型的变量时,创建的变量被称作标头(header)值。字符串也是一种引用类型。
标头值:是包含一个指向底层数据结构的指针,所以通过复制来传递一个引用类型的值的副本,本质上就是在共享底层数据结构。
三、结构类型 结构类型可以用来描述一组数据值,这组值的本质即可以是原始的,也可以是非原始的。 有两个例子提供: type Time struct { // sec 给出自公元1 年1 月1 日00:00:00 // 开始的秒数 sec int64 // nsec 指定了一秒内的纳秒偏移, // 这个值是非零值, // 必须在[0, 999999999]范围内 nsec int32 // loc 指定了一个Location, // 用于决定该时间对应的当地的分、小时、 // 天和年的值 // 只有Time 的零值,其loc 的值是nil // 这种情况下,认为处于UTC 时区 loc *Location } Now方法 func Now() Time { sec, nsec := now() return Time{sec + unixToInternal, nsec, Local} } Time对象的方法 func (t Time) Add(d Duration) Time { t.sec += int64(d / 1e9) nsec := int32(t.nsec) + int32(d%1e9) if nsec >= 1e9 { t.sec++ nsec -= 1e9 } else if nsec < 0 { t.sec-- nsec += 1e9 } t.nsec = nsec } Now方法和Time对象的方法,可以看到传入和参数和返回的值全是值传递的。也就是说返回的都是一个值的副本。
有如下的结构体,为什么File中只有一个*file,这个目前未知,这样设计的好处? // File 表示一个打开的文件描述符 type File struct { *file } // file 是*File 的实际表示 // 额外的一层结构保证没有哪个os 的客户端 // 能够覆盖这些数据。如果覆盖这些数据, // 可能在变量终结时关闭错误的文件描述符 type file struct { fd int name string dirinfo *dirInfo // 除了目录结构,此字段为nil nepipe int32 // Write 操作时遇到连续EPIPE 的次数 } open方法,参数传入了File的指针 func Open(name string) (file *File, err error) { return OpenFile(name, O_RDONLY, 0) } File对象的方法,是引用传递的 func (f *File) Chdir() error { if f == nil { return ErrInvalid } if e := syscall.Fchdir(f.fd); e != nil { return &PathError{"chdir", f.name, e} } return nil } 为什么用引用,因为File 类型的值具备非原始的本质,所以总是应该被共享,而不是被复制。 这一章节主要想说明什么呢?主要是想说,在设计一个方法的参数、返回值、接收者的时候,需要考虑类型本身是什么东西,例如值类型,这个本身就是传值的复制类型,而引用类型的本身就是传递地址的。对于结构类型需要看类型本身是需要被改写的还是一个副本、
|
请发表评论