go语言基础---2基本语法

  • go文件结构:

    • package,创建包。Go语言以“包”作为管理单位,每个 Go 源文件必须先声明它所属的包。包名可以与其目录名不同。
    • main 包是Go语言程序的入口包,一个Go语言程序必须有且仅有一个 main 包。如果一个程序没有 main 包,那么编译时将会出错,无法生成可执行文件。
    • import "name"导入包,多个包用{ }括起来。
  • 语句结尾不需要;,Go 编译器会自动添加,自己加也可以。

1 变量

变量的基本类型
  • bool:true/false

    布尔型无法参与数值运算,也无法与其他类型进行转换。

  • string UTF-8编码的变宽字符序列,每个字符都用一个或多个字节表示(Java是采用UTF-16来表示,每个字符都对应2个字节)。

    一般的比较运算符(==、!=、<、<=、>=、>)是通过在内存中按字节比较来实现字符串比较的,比较的是字符串自然编码的顺序。
    字符串所占的字节长度可以通过函数 len() 来获取,例如 len(str)。

  • 有符号整型 int(依赖不同平台的实现 32或64位)、int8 (-128 到 127)、int16 (-32768 到 32767)、int32 (又名rune-2147483648 到 2147483647)、int64

  • 无符号整型 uint(与int一样)、uint8(又名byte 0~255)、uint16 (0 到 65535)、uint32 (0 到 4294967295)、uint64uintptr(存放指针,位数依赖平台)

    在二进制传输、读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用 int 和 uint。

  • float32float64:float32能取到的最大值为math.MaxFloat32,精度大约十个十进制数;float64精度约15个十进制数。

  • complex64complex128 :复数,实部虚部都是float32,complex128 为复数的默认类型。

    声明复数:var name complex128 = complex(x, y)
    real(z) 来获得复数z的实部;通过imag(z) 获得复数z的虚部

变量的声明
  • 声明变量:var name type 变量类型放在变量名之后。

  • 当一个变量被声明之后,系统自动赋予它该类型的零值。所有的内存在 Go 中都是经过初始化的。

    在C语言中,变量在声明时,并不会对变量对应内存区域进行清理操作。此时,变量值可能是完全不可预期的结果。所以声明时要初始化。微软的 VC 编译器会将未初始化的栈空间以 16 进制的 0xCC 填充,而未初始化的堆空间使用 0xCD 填充,而 0xCCCC 和 0xCDCD 在中文的 GB2312 编码中刚好对应“烫”和“屯”字。

  • 变量初始化:var 变量名 类型 = 表达式 例如:var a int = 100

    编译器会根据等号右边的表达式推导变量的类型,因此可以省略类型。
    编译器会尽量提高精确度,以避免计算中的精度损失,浮点型会推导为float64

  • 批量声明:

    var (
    	a int
    	b string
    	c []float32
    	d func() bool   //d是返回值是bool的函数名
    )
    
  • 简短声明格式:变量 := 表达式 例如:i,j := 0,1

    该声明方式只能用在函数内部,定义变量的同时显式初始化,不能提供数据类型。
    如果已经声明过变量,再使用短变量声明并初始化则会编译错误。也就是说短变量声明的左值必须是没有定义过的变量。

    注意:在多个短变量声明和赋值中,至少有一个新声明的变量出现在左值中,即便其他变量名可能是重复声明的,编译器也不会报错。例如:

    //net.Dial按指定协议和地址发起网络连接,函数有两个返回值,一个是连接对象(conn),一个是错误对象(err)
    conn, err := net.Dial("tcp", "127.0.0.1:8080")   
    conn2, err := net.Dial("tcp", "127.0.0.1:8080")   //conn2是新定义的变量,即使err已经声明过编译也不会报重复定义
    
变量的多重赋值
  • 由于Go中多个变量可以同时赋值:i, j = 0, 1,所以可能简单的进行变量交换b, a = a, b
匿名变量
  • '_'用下划线(空白标识符)声明的变量,任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用,也不可以使用这个标识符作为变量对其它变量进行赋值或运算。
  • 在使用多重赋值时,如果不需要在左值中接收变量,可以使用匿名变量。(或者只想接收函数部分返回值时)
  • 匿名变量不占用内存空间,不会分配内存。匿名变量与匿名变量之间也不会因为多次声明而无法使用。
变量作用域
  • 在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,函数的参数和返回值变量都属于局部变量。
  • 局部变量不是一直存在的,它只在定义它的函数被调用后存在,函数调用结束后这个局部变量就会被销毁。
  • 在函数体外声明的变量称之为全局变量,全局变量只需要在一个源文件中定义,就可以在所有源文件中使用(不包含这个全局变量的源文件需要使用“import”关键字引入全局变量所在的源文件之后才能使用这个全局变量)。
  • 全局变量声明必须以 var 关键字开头,如果想要在外部包中使用全局变量的首字母必须大写。
  • Go语言程序中全局变量与局部变量名称可以相同,但是函数体内的局部变量会被优先考虑。
  • 在定义函数时函数名后面括号中的变量叫做形式参数。形式参数只在函数调用时才会生效,函数调用结束后就会被销毁,在函数未被调用时,函数的形参并不占用实际的存储单元,也没有实际值。
    形式参数会作为函数的局部变量来使用。
字符串
  • Go语言中字符串的内部实现使用 UTF-8 编码。

  • 字符串拼接:str := "aaa" + "bbb"

  • 多行字符串:多行字符串用反引号包起来,可以跨行,其中的转义字符无效,会被原样输出。

  • 字符串长度:len() 返回int型,表示字符串的 ASCII 字符个数或字节长度。例如:len("中国") = 6

    如果希望按习惯上的字符个数来计算,需要使用 Go 语言中 UTF-8 包提供的 RuneCountInString() 函数:utf8.RuneCountInString("中国") = 2
    ASCII 字符串长度使用 len() 函数。
    Unicode 字符串长度使用 utf8.RuneCountInString() 函数。

  • 字符串遍历:ASCII 字符串遍历直接使用下标。Unicode 字符串遍历用 for range。

    theme := "狙击 start"
    for i := 0; i < len(theme); i++ {
        fmt.Printf("ascii: %c  %d\n", theme[i], theme[i])
    }
    
    for _, s := range theme {
        fmt.Printf("Unicode: %c  %d\n", s, s)
    }
    
  • 修改字符串:Go 语言的字符串是不可变的,修改字符串时,可以将字符串转换为 []byte 进行修改,[]byte 和 string 可以通过强制类型转换互转。

    angel := "Heros never die"
    angleBytes := []byte(angel)
    for i := 5; i <= 10; i++ {
        angleBytes[i] = ' '
    }
    fmt.Println(string(angleBytes))
    //输出:Heros     die
    

    字符串不可变有很多好处,如天生线程安全,大家使用的都是只读对象,无须加锁;再者,方便内存共享,而不必使用写时复制(Copy On Write)等技术;字符串 hash 值也只需要制作一份。
    代码中实际修改的是 []byte,[]byte 在 Go 语言中是可变的,本身就是一个切片。

  • 截取字符串: str[起始位置:结束为止], 结束位置省略表示到末尾。

  • 字符类型:uint8(byte)代表一个ASCII码字符,rune(int32) 代表一个UTF-8字符。

    Unicode 包中内置了一些用于测试字符的函数:判断是否为字母:unicode.IsLetter(ch)
    判断是否为数字:unicode.IsDigit(ch)
    判断是否为空白符号:unicode.IsSpace(ch)

数据类型转换
  • Go语言不存在隐式类型转换,因此所有的类型转换都必须显式的声明。
  • 只有相同底层类型的变量之间可以进行相互转换(如将 int16 类型转换成 int32 类型),不同底层类型的变量相互转换时会引发编译错误(如将 bool 类型转换为 int 类型)。
变量逃逸分析
  • 在 C/C++ 语言中,需要开发者自己学习如何进行内存分配,选用怎样的内存分配方式来适应不同的算法需求。比如,函数局部变量尽量使用栈,全局变量、结构体成员使用堆分配等。Go语言将这个过程整合到了编译器中,命名为“变量逃逸分析”。通过编译器分析代码的特征和代码的生命周期,决定应该使用堆还是栈来进行内存分配。

  • 逃逸分析是一种确定指针动态范围的方法——分析在程序的哪些地方可以访问到指针。也是就是说逃逸分析是解决指针作用范围的编译优化方法。函数中生成一个新对象:

    如果分配到栈上,待函数返回资源就被回收了
    如果分配到堆上,函数返回后交给gc来管理该对象资源

    栈资源的分配及回收速度比堆要快,所以逃逸分析最大的好处应该是减少了GC的压力。

  • 运行代码时使用go run -gcflags "-m -l" main.go,可以进行变量逃逸分析。

    -gcflags 参数是编译参数
    -m 表示进行内存分配分析
    -l 表示避免程序内联,也就是避免进行程序优化。

  • 变量逃逸情况分很多种,例如栈空间不足逃逸

2 指针

  • Go语言为程序员提供了控制数据结构指针的能力,但是,并不能进行指针运算。
  • 指针(pointer)在Go语言中可以被拆分为两个核心概念:
    类型指针,允许对这个指针类型的数据进行修改,传递数据可以直接使用指针,而无须拷贝数据,类型指针不能进行偏移和运算。
    切片,由指向起始元素的原始指针、元素数量和容量组成。
  • 对变量进行取地址操作使用&操作符,可以获得这个变量的指针变量。
    指针变量的值是指针地址。
    对指针变量进行取值操作使用*操作符,可以获得指针变量指向的原变量的值。

【参考文档】
Go语言基本语法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值