• Go语言类型的本质


    如果给这个类型增加或者删除某个值,是要创建一个新值,还是要更改当前的值?

    如果是要创建一个新值,该类型的方法就使用值接收者。

    如果是要修改当前值,就使用指针接收者。

    这个答案也会影响程序内部传递这个类型的值的方式:是按值做传递,还是按指针做传递。

    保持传递的一致性很重要。

     

    一、内置类型

    字符串(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 类型的值具备非原始的本质,所以总是应该被共享,而不是被复制。

    这一章节主要想说明什么呢?主要是想说,在设计一个方法的参数、返回值、接收者的时候,需要考虑类型本身是什么东西,例如值类型,这个本身就是传值的复制类型,而引用类型的本身就是传递地址的。对于结构类型需要看类型本身是需要被改写的还是一个副本、

     

  • 相关阅读:
    Leastsq 最小二乘法拟合一次函数简单入门例子
    Matplotlab 基础画图
    plot(x,y1,'g',x,y2,'b--o',x,y3,'c*') 方法中对数据类型的要求和线条类型和颜色的设置
    [Java] 获取255年前芝加哥格式化时间
    [SoapUI] 在Assertion和Groovy Script里获取RequestId
    [SoapUI] 在脚本里写code执行某个step
    [SoapUI] 获取TestStep的状态
    [SoapUI] 判断失败继续执行
    [Java] 获取两个日期间的所有日期
    [Excel] excel中如何快速统计出各个项出现的次数?
  • 原文地址:https://www.cnblogs.com/dcz2015/p/10103254.html
Copyright © 2020-2023  润新知