go语言-golang基础-变量、常量、类型

golang基础

1 第一个go基础

基本的语法机构

// 定义包main
package main //go源文件开头必须使用package声明代码所属包,包是go代码分发的最基本单位。

import "fmt" //导入程序依赖的标准包fmt

//func用于定义函数。main函数是程序入口,若程序需要运行必须声明main函数,main函数无参数也无返回值
func main() {
    /*
        这是一个注释
        这里调用fmt包下的Println函数打印内容到控制台
    */
    fmt.Println("hello world") //调用fmt.Println函数将参数信息打印到控制台上。打印hello world到控制台
}
// 注释有两种格式。
//行注释f
/*
块注释
*/

编译和运行

1. go build: 用于编译&链接程序或包
例子:go build -work -x -o helloworld.exe main.go

2. go run:用于直接运行程序
例子:go run -work -x main.go
go run helloword.go
3. go clean:清除编译文件

4. 常用参数:
    -x: 打印编译过程执行的命令,并完成编译或运行 
    -n: 只打印编译过程执行命令
    -work:打印编译过程的临时目录
    -o: 指定编译结果文件

2. 程序结构

Go 源文件以 package 声明开头,说明源文件所属的包,接着使用 import 导入依赖的包,其 次为包级别的变量、常量、类型和函数的声明和赋值。函数中可定义局部的变量、常量

3. 基本组成元素

  1) 标识符:程序中定义的名字。 变量名,常量名字,函数名字,自定义类型,接口,包名

     规范:

     1.必须满足:组成只能由非空的unicode编码字符串、数字、下划线组成

     2.必须满足:必须由Unicode字符或下划线开头
     3.不能使用go语言关键字
       4.避免使用go语言预定义标识符
   建议:
       1. 建议使用驼峰式命名
       2. 标识符区分大小写
     Go 语言提供一些预先定义的标识符用来表示内置的常量、类型、函数,在自定义标识符时 应避免使用:、
   内置常量:true、false、nil、iota
         内置类型:bool、byte、rune、int、int8、int16、int32、int64、uint、uint8、unit16、unit32、unit64、uintptr、float32、float64、complex64、complex128、string、error
         内置函数:make、len、cap、new、append、copy、close、delete、complex、real、imag、panic、recover
         空白标识符:_
  2) 关键字
      关键字用于特定的语法结构,Go 语言定义 25 关键字:
    声明:import、package
      实体声明和定义:chan、const、func、interface、map、struct、type、var
      流程控制:break、case、continue、default、defer、else、fallthrough、for、go、goto、 if、range、return、select、switch
  3) 字面量
      字面量是值的表示方法,常用与对变量/常量进行初始化,主要分为:
      标识基础数据类型值的字面量,例如:0, 1.1, true, 3 + 4i, 'a', "我爱中国"
      构造自定义的复合数据类型的类型字面量,例如:type Interval int
      用于表示符合数据类型值的复合字面量,用来构造array、slice、map、struct的值,
      例如:{1, 2, 3}
  4) 操作符
     算术运算符:+、-、*、/、%、++、--
     关系运算符:>、>=、<、<=、==、!=
     逻辑运算符:&&、||、!
     位运算符:&、|、^、<<、>>、&^
     赋值运算符:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=
     其他运算符:&(单目)、*(单目)、.(点)、-(单目)、...、<-
  5) 分割符
  小括号(), 中括号[],大括号(),分号;,逗号,
4. 声明
  声明语句用于定义程序的各种实体对象,主要有:
  声明变量的var
  声明常量的const   
  声明函数的func   
  声明类型的type
5. 变量
  变量是几乎所有编程语言中最基本的组成元素。从根本上说,变量相当于是对一块数据存储 空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来使用这块存储空间,对存储空间的内容进行访问和修改。
5.1 变量的定义

  ⚫ var变量名变量类型=值
    定义变量并进行初始化,例如:var name string = "silence"
  ⚫ var 变量名 变量类型
    定义变量使用零值进行初始化,例如:var age int
  ⚫ var变量名=值
    定义变量,变量类型通过值类型进行推导
    例如: var isBoy = true
  ⚫ var 变量名1, 变量名2 , ..., 变量名n 变量类型
    定义多个相同类型的变量并使用零值进行初始化
    例如:var prefix, suffix string
  ⚫ var变量名1, 变量名2 , ..., 变量名n 变量类型 = 值1, 值2, ..., 值n
    定义多个相同类型的变量并使用对应的值进行初始化,例如:var prev, next int = 3, 4
  ⚫ var变量名1, 变量名2 , ..., 变量名n = 值1, 值2, ..., 值n
    定义多个变量并使用对应的值进行初始化,变量的类型使用值类型进行推导,类型可不相同,例如:var name, age = "silence", 30
  ⚫ 批量定义
    var (
      变量名1 变量类型1 = 值1 变量名2 变量类型2 = 值2
    ) 定义多个变量并进行初始化,批量复制中变量类型可省略 例如:
    var (
      name string = "silence"
      age int = 30
    )
初始化表达式可以使用字面量、任何表达式、函数

package main

import "fmt"

func main() {
    //变量 给数据起一个名字
    var msg string = "hello Jordan"
    fmt.Println(msg)
    //其他代码
    fmt.Println(msg)
    //其他代码
    fmt.Println(msg)
    //其他代码
    fmt.Println(msg)

   //var变量名 变量类型 = 值
   var name string = "Jordan" //定义变量类型并初始化值. 
    //var 变量名 变量类型
   var zeroString string      //定义变量类型,但不定义初始化值
    
   //var变量名 = 值
   var typeString = "Jordan1" // 定义变量省略类型,不能省略初始化值。 通过对应的值类型推导出变量的类型

    shortString := "Jordan3" //短声明(必须在函数内包含函数内子块使用,不能在包级别使用)。通过对应的值类型推导出变量的类型

    fmt.Println(name, zeroString, typeString, shortString)
    

  
    // 函数内(块定义的变量必须使用)
    /*
    var name string = "Jordan"
    var msg string = "hello world"
    var desc string
    */
    // 批量定义.定义多个变量并进行初始化,批量复制中变量类型可省略
    var (
    name string = "Jordan"
    msg = "hello world"
    desc string
    )
    /*
    x:="x"
    y:="y"
    */
    // var变量名1, 变量名2 , ..., 变量名n = 值1, 值2, ..., 值n。定义多个变量并使用对应的值进行初始化,变量的类型使用值类型进行推导,类型可不相同,例如:
    var name1, age1 = "silence", 30
    //短声明
    x, y := "x1", "y1"
    fmt.Println(name, msg, desc, name1, age1, x, y)
}

5.2 简短声明

在函数内可以通过简短声明语句声明并初始化变量,可通过简短声明同时声明和初始化多个 变量,需要注意操作符左侧的变量至少有一个未定义过

package main
import "fmt"
func main() {

    n1, n2 := 12, 123
    fmt.Println(n1, n2)
    n2, n3 := 34, 35
    fmt.Println(n2, n3)
} 

5.3 变量赋值

在Go语法中,变量初始化和变量赋值是两个不同的概念。下面为声明一个变量之后的赋值过程:

var v10 int 
v10 = 123

Go语言的变量赋值与多数语言一致,但Go语言中提供了C/C++程序员期盼多年的多重赋值功 能,比如下面这个交换i和j变量的语句:

i, j = j, i

例:

package main
import "fmt"
func main() {

    n1, n2 := 12, 123
    fmt.Println(n1, n2)
    n1, n2 = n2, n1
    fmt.Println(n1, n2)
} 

5.4 匿名变量

      我们在使用传统的强类型语言编程时,经常会出现这种情况,即在调用函数时为了获取一个 值,却因为该函数返回多个值而不得不定义一堆没用的变量。在Go中这种情况可以通过结合使 用多重返回和匿名变量来避免这种丑陋的写法,让代码看起来更加优雅。
      假设GetName()函数的定义如下,它返回3个值,分别为firstName、lastName和 nickName:

func GetName() (firstName, lastName, nickName string) {

  return "May", "Chan", "Chibi Maruko"
}

若只想获得nickName,则函数调用语句可以用如下方式编写:

_, _, nickName := GetName()

这种用法可以让代码非常清晰,基本上屏蔽掉了可能混淆代码阅读者视线的内容,从而大幅 降低沟通的复杂度和代码维护的难度。

6 常量 

在Go语言中,常量是指编译期间就已知且不可改变的值。常量可以是数值类型(包括整型、浮点型和复数类型)、布尔类型、字符串类型等。

6.1 常量定义
通过const关键字,你可以给字面常量指定一个友好的名字: 

//const常量名类型=值
const Pi float64 = 3.14159265358979323846

//const 常量名 = 值
const zero = 0.0 // 无类型浮点常量 

//批量定义
const (
  size int64 = 1024 
  eof = -1 // 无类型整型常量
)
const u, v float32 = 0, 3 // u = 0.0, v = 3.0,常量的多重赋值
const a, b, c = 3, 4, "foo" //a=3,b=4,c="foo", 无类型整型和字符串常量

Go的常量定义可以限定常量类型,但不是必需的。如果定义常量时没有指定类型,那么它与字面常量一样,是无类型常量。

常量定义的右值也可以是一个在编译期运算的常量表达式,比如

const mask = 1 << 3 

由于常量的赋值是一个编译期行为,所以右值不能出现任何需要运行期才能得出结果的表达
式,比如试图以如下方式定义常量就会导致编译错误:

const Home = os.GetEnv("HOME") 

原因很简单,os.GetEnv()只有在运行期才能知道返回结果,在编译期并不能确定,所以无法作为常量定义的右值。

6.2 预定义常量
Go语言预定义了这些常量:true、false和iota。
iota比较特殊,可以被认为是一个可被编译器修改的常量,在每一个const关键字出现时被重置为0,然后在下一个const出现之前,每出现一次iota,其所代表的数字会自动增1。
从以下的例子可以基本理解iota的用法:

const (            // iota被重设为0 
        c0 = iota     // c0 == 0
        c1 = iota     // c1 == 1
        c2 = iota    // c2 == 2
)        
    
const (
        a = 1 << iota     // a == 1 (iota在每个const开头被重设为0)
        b = 1 << iota     // b == 2
        c = 1 << iota     // c == 4
)        
    
const (
        u         = iota * 42     // u == 0
        v float64 = iota * 42    // v == 42.0
        w         = iota * 42    // w == 84
)

const x = iota     // x == 0 (因为iota又被重设为0)

const y = iota     // y == 0 (因为iota又被重设为0)

果两个const的赋值语句的表达式是一样的,那么可以省略后一个赋值表达式。因此,上面的前两个const语句可简写为:

const (           // iota被重设为0 

    c0 = iota     // c0 == 0
    c1            // c1 == 1
    c2            // c2 == 2
)

const (                
    a = 1 <<iota  // a == 1 (iota在每个const开头被重设为0)
    b             // b == 2
    c             // c == 4
)

6.3 枚举
枚举指一系列相关的常量,比如下面关于一个星期中每天的定义。通过上一节的例子,我们看到可以用在const后跟一对圆括号的方式定义一组常量,这种定义法在Go语言中通常用于定义枚举值。Go语言并不支持众多其他语言明确支持的enum关键字。
下面是一个常规的枚举表示法,其中定义了一系列整型常量:

const (
    Sunday = iota
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
    numberOfDays // 这个常量没有导出
)

同Go语言的其他符号(symbol)一样,以大写字母开头的常量在包外可见。
以上例子中numberOfDays为包内私有,其他符号则可被其他包访问。

7 基础数据类型
Go语言内置以下这些基础类型:

  • 布尔类型:bool。
  • 整型:int8、byte、int16、int、uint、uintptr等。
  • 浮点类型:float32、float64。
  • 复数类型:complex64、complex128。
  • 字符串:string。
  • 字符类型:rune。
  • 错误类型:error。

此外,Go语言也支持以下这些复合类型:

  • 指针(pointer)
  • 数组(array)
  • 切片(slice)
  • 字典(map)
  • 通道(chan)
  • 结构体(struct)
  • 接口(interface)
在这些基础类型之上Go还封装了下面这几种类型:int、uint和uintptr等。这些类型的 特点在于使用方便,但使用者不能对这些类型的长度做任何假设。对于常规的开发来说,用int 和uint就可以了,没必要用int8之类明确指定长度的类型,以免导致移植困难。

7.1 布尔类型
Go语言中的布尔类型与其他语言基本一致,关键字也为bool,可赋值为预定义的true和false示例代码如下:

var v1 bool
v1 = true
v2 := (1 == 2) // v2也会被推导为bool类型

布尔类型不能接受其他类型的赋值,不支持自动或强制的类型转换。以下的示例是一些错误 的用法,会导致编译错误:

var b bool
b=1    // 编译错误
b = bool(1) // 编译错误

以下的用法才是正确的:

var b bool
b = (1!=0) // 编译正确
fmt.Println("Result:", b) // 打印结果为Result: true

例:

package main

import "fmt"

func main() {
    isGirl := false
    fmt.Printf("%T,%#v\n", isGirl, isGirl)

    //操作
    //逻辑运算
    a, b, c, d := true, true, false, false
    //与(&&):左操作数和右操作数都为true,结果为true &&
    fmt.Println("a,b:", a && b) // true && true :true
    fmt.Println("a,c:", a && c) // true && false:false
    fmt.Println("c,b:", c && b) // false && true :false
    fmt.Println("c,d:", c && d) // false && false :false
    //或(||):左操作数和右操作数有一个为true,结果为true ||
    fmt.Println("a,b:", a || b) //true||true: true
    fmt.Println("a,c:", a || c) // true || false:true
    fmt.Println("c,b:", c || b) // false || true :true
    fmt.Println("c,d:", c || d) // false || false :false
    //非(!)
    fmt.Println("a:", !a) //true: false
    fmt.Println("c:", !c) //false: true

    //关系
   // a) 等于(==)
   // b) 不等于(!=)
    fmt.Println(a == b) //true==true:true
    fmt.Println(c != b) //false!=true:true
    fmt.Println(a == c) //true==false:false
    fmt.Println(a != c) //true != false: true

    fmt.Printf("%t,%t", a, a)
    var bbb bool
    fmt.Println(bbb)

}

使用 fmt.Printf 进行格式化参数输出,占位符: %t

7.2 整型

整型是所有编程语言里最基础的数据类型。Go语言提供了5种有符号、5种无符号、1种指针、1种单字节、1种单个unicode字符(unicode码点),共13种整数类型,零值均为0。

类型名

字节宽度

说明&取值范围

int

与平台有关,32 位 系统4字节,64位 系统8字节

有符号整型

uint

与平台有关,32 位 系统4字节,64位 系统8字节

无符号整形

rune

4字节

Unicode 码点,取值范围同 uint32

int8

1字节

用 8 位表示的有符号整型,取值范围为:[-128, 127]

int16

2字节

用 16 位表示的有符号整型,取值范围为: [-32768,32767]

int32

4字节

用 32 位表示的有符号整型,取值范围为: [-2147483648,2147483647]

int64

8字节

用 64 位表示的有符号整型,取值范围为: [-9223372036854775808,9223372036854775807]

uint8

1字节

用 8 位表示的无符号整型,取值范围为:[0,255]

uint16

2字节

用 16 位表示的无符号整型,取值范围为:[0, 65535]

uint32

4字节

用 32 位表示的无符号整型,取值范围为:[0, 4294967295]

uint64

8字节

用 64 位表示的无符号整型,取值范围为:[0, 18446744073709551615]

byte

1字节

字节类型,取值范围同 uint8

uintptr

与平台有关,32 位 系统4字节,64位 系统8字节

指针值的无符号整型

1)类型表示

需要注意的是,int和int32在Go语言里被认为是两种不同的类型,编译器也不会帮你自动 做类型转换,比如以下的例子会有编译错误:

var value2 int32
value1 := 64 // value1将会被自动推导为int类型
value2 = value1 // 编译错误

编译错误类似于:
cannot use value1 (type int) as type int32 in assignment。 使用强制类型转换可以解决这个编译错误:

value2 = int32(value1) // 编译通过

类型转换

当然,开发者在做强制类型转换时,Go 不会对自动对数据类型转换,因此左、右操作数类型必须一致或某个字面量,可通过类型名(数据)的语法将数据转换为对应类型。需要注意数据长度被截短而发生的数据精度损失(比如将浮点数强制转为整数)和值溢出(值超过转换的目标类型的值范围时)问题。


2)数值运算
Go语言支持下面的常规整数运算:+、-、*、/和%、++、--。加减乘除就不详细解释了,需要说下的 是,% 和在C语言中一样是求余运算,比如:

5%3  // 结果为:2

3) 比较运算
Go语言支持以下的几种比较运算符:>、<、==、>=、<=和!=。这一点与大多数其他语言相 同,与C语言完全一致。
下面为条件判断语句的例子:

i, j := 1, 2 if i == j {
    fmt.Println("i and j are equal.")
}

两个不同类型的整型数不能直接比较,比如int8类型的数和int类型的数不能直接比较,但各种类型的整型变量都可以直接与字面常量(literal)进行比较,比如:

var i int32
var j int64
i, j = 1, 2
if i == j {                // 编译错误 
    fmt.Println("i and j are equal.")
}
if i == 1 || j == 2 {        // 编译通过 
    fmt.Println("i and j are equal.")
}

4)位运算

位运算符:&、|、^、<<、>>、&^ 对于负整数在计算机中使用补码进行表示,对应正整数二进制表示取反+1 针对左、右移的右操作数必须为无符号整型。

5)占位符

使用 fmt.Printf 进行格式化参数输出,占位符:

  • %b:二进制

  • %c:字符

  • %d:十进制

    ◼ %+d表示对正整数带+符号
    ◼ %nd表示最小占位n个宽度且右对齐
    ◼ %-nd表示最小占位n个宽度且左对齐
    ◼ %0nd表示最小占位n个宽度且右对齐,空字符使用0填充

  • %o:八进制,%#o带0的前缀

  • %x、%X:十六进制,%#x(%#X)带0x(0X)的前缀

  • %U: Unicode 码点,%#U 带字符的 Unicode 码点

  • %q:带单引号的字符

6)常用包:

  • math
  • math/rand

例:

package main

import "fmt"

func main() {
    // 正数类型
    // 标识符:int/int*/uintptr/byte
    // 字面两:十进制,八进制,十六进制
    var age int = 30
    fmt.Printf("%T %d\n", age, age)
    fmt.Println(0777, 0x10)

    //操作
    // 算术运算(+,-,*,/,%,++,--)
    fmt.Println(1 + 2)
    fmt.Println(3 - 10)
    fmt.Println(3 * 4)
    fmt.Println(9 / 2)
    fmt.Println(9 % 2)
    //fmt.Println(9 % 0)

    age++
    fmt.Println(age)
    age--
    fmt.Println(age)

    //关系运算(== != < <= > >=)
    fmt.Println(2 == 3)
    fmt.Println(2 != 3)
    fmt.Println(2 < 3)
    fmt.Println(2 <= 3)
    fmt.Println(2 > 3)
    fmt.Println(2 >= 3)

    //位运算 二进制运算 10 =>2
    // & | ^ << >> &^
    //十进制转成二 进制
    //7 => 0111
    //2 => 0010
    //7&2 => 0111 & 0010 => 0010 =>2
    //7|2 => 0111 | 0010 => 0111 =>7
    //7 ^2 => 0111 ^ 0010 => 0101 =>5
    //2 << 1 => 0010 << 1 => 0100 =>4
    //2 >> 1 => 0010 >> 1 => 0001 => 1
    // 7 &^2 => 0111 &^ 0010 => 0101=>5

    fmt.Println(7 & 2)
    fmt.Println(7 | 2)
    fmt.Println(7 ^ 2)
    fmt.Println(2 << 1)
    fmt.Println(2 >> 1)
    fmt.Println(7 &^ 2)

    //赋值(=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=,&^=)
    // a+b ==> a=a+b
    age = 1
    age += 3 // age = age+3
    fmt.Println(age)

    //int.uint/byte/rune/int*
    var intA int = 10
    var uintB uint = 3
    fmt.Println(intA + int(uintB))
    fmt.Println(uint(intA) + uintB)

    //大--->小,转换可能出现溢出
    var intC int = 0XFFFF
    fmt.Println(intC, uint8(intC), int8(intC))

    //fmt.Println
    //int/uint/int*/uint*
    //byte,rune
    var a byte = 'A'
    var w rune = ''
    fmt.Println(a, w)

    fmt.Printf("%T %d %b %o %x \n", age, age, age, age, age)
    fmt.Printf("%T %c \n", a, a)
    fmt.Printf("%T %q %U\n", w, w, w)
    //fmt.Printf()


}
package main

import "fmt"

func main() {
    var age int8 = 31
    var age1 = 31
    fmt.Printf("%T,%#v,%d\n", age, age, age)
    fmt.Printf("%T,%#v,%d\n", age1, age1, age1)

    a, b := 5, 2
    fmt.Println(a + b)
    fmt.Println(a - b)
    fmt.Println(a * b)
    fmt.Println(a / b)
    fmt.Println(a % b)

    a++
    b--
    fmt.Println(a, b)

    //关系运算
    fmt.Println(a > b)
    fmt.Println(a < b)
    fmt.Println(a == b)
    fmt.Println(a >= b)
    fmt.Println(a <= b)

    //仅了解 位运算

    var (
        i   int   = 1
        i32 int32 = 1
        i64 int64 = 1
    )
    //类型转换,type(value) int32(i) int64(i) int(i64)
    fmt.Printf("%T\n", i+int(i32))
    fmt.Printf("%T\n", i+int(i64))
    fmt.Printf("%T\n", i32+int32(i64))
    fmt.Printf("%T\n", i64+int64(i))

    var (
        aaa          byte = 'A'
        aint         byte = 64
        unicodePoint rune = ''
    )
    fmt.Println(aaa, aint, unicodePoint)
    //%d 十进制
    //%b 二进制
    //%o 八进制
    //%x 十六进制
    //%U unicode码点
    //%q带单引号的字符
    fmt.Printf("%d %b %o %x %U %c %c", aaa, 15, 15, 15, unicodePoint, aaa, 65)
}

 

7.3 浮点型

浮点型用于表示包含小数点的数据,比如1.234就是一个浮点型数据。Go语言中的浮点类型 采用IEEE-754标准的表达方式。
1) 浮点数表示
Go语言定义了两个类型float32和float64,其中float32等价于C语言的float类型, float64等价于C语言的double类型。
字面量:

  • 十进制表示法:3.1415926
  • 科学记数法:1e-5

在Go语言里,定义一个浮点数变量的代码如下:

var fvalue1 float32
fvalue1 = 12
fvalue2 := 12.0 // 如果不加小数点,fvalue2会被推导为整型而不是浮点型

对于以上例子中类型被自动推导的fvalue2,需要注意的是其类型将被自动设为float64, 而不管赋给它的数字是否是用32位长度表示的。因此,对于以上的例子,下面的赋值将导致编译 错误:

fvalue1 = fvalue2
而必须使用这样的强制类型转换:
fvalue1 = float32(fvalue2)

2)常用操作

  • 算术运算(+ - * / ++ --)
  • 关系运算(> >= < <= ~=)
  • 赋值(= += -= *= /=)
package main

import "fmt"

func main() {
    // float32,float64
    //字面量:十进制表示法,科学计数表示法
    // MEN=> M*10^N
    //1
    var height float64 = 1.68
    fmt.Printf("%T %f\n", height, height)
    var weight float64 = 13.05E1
    fmt.Println(weight)

    //操作
    //算术运算(+ - * / ++ --)
    fmt.Println(1.1 + 1.2)
    fmt.Println(1.1 - 1.2)
    fmt.Println(1.1 * 1.2)
    fmt.Println(1.1 / 1.2)

    height++
    fmt.Println(height)
    height--
    fmt.Println(height)

    //关系运算(> >= < <= ~=)因为浮点数不是一种精确的表达方式,所以像整型那样直接用==来判断两个浮点数是否相等 是不可行的,这可能会导致不稳定的结果。
    fmt.Println(1.1 > 1.2)
    fmt.Println(1.1 < 1.2)
    fmt.Println(1.1 <= 1.2)
    fmt.Println(1.1 >= 1.2)
    fmt.Println(1.2-1.1 <= 0.005)

    // 赋值(= += -= *= /=)
    height += 0.05
    fmt.Println(height)

    fmt.Printf("%T,%T\n", 1.1, height)

    fmt.Printf("%5.2f\n", height)


}

3)占位符

使用 fmt.Printf 进行格式化参数输出,占位符:

  • %f、%F:十进制表示法

    ◼ %n.mf表示最小占n个宽度并且保留m位小数

  • %e、%E:科学记数法表示

  • %g、%G:自动选择最紧凑的表示方法%e(%E)或%f(%F)

4)常用包

  •  math
  • math/rand

7.4 复数类型

Go提供complex64和complex128两种复数类型,针对complex64复数的实部和虚部均使用float32,针对complex128复数的实部和虚部均使用float64
字面量:
十进制表示法:1 + 2i,, i*i = -1, 1 为实部,2 为虚部
常用函数:
complex: 工厂函数,通过两个参数创建一个复数
real:用于获取复数的实部
imag: 用于获取复数的虚部

1)复数表示 复数表示的示例如下:

var value1 complex64     // 由2个float32构成的复数类型 
value1 = 3.2 + 12i         
value2 := 3.2 + 12i            // value2是complex128类型
value3 := complex(3.2, 12)    // value3结果同 value2

2)实部与虚部
对于一个复数z = complex(x, y),就可以通过Go语言内置函数real(z)获得该复数的实 部,也就是x,通过imag(z)获得该复数的虚部,也就是y。

3)常用包

  • math/cmplx

 

7.5 字符串

Go语言内置了字符串类型,使用 string 表示

1)字面量:

  • 可解析字符串:通过双引号(")来创建,不能包含多行,支持特殊字符转义序列
  • 原生字符串:通过反引号(`)来创建,可包含多行,不支持特殊字符转义序列

2)特殊字符:

  • \\:反斜线
  • \':单引号
  • \":双引号
  • \a:响铃
  • \b:退格
  • \f:换页
  • \n:换行
  • \r:回车
  • \t:制表符
  • \v:垂直制表符
  • \ooo:3个8位数字给定的八进制码点的Unicode字符(不能超过\377)
  • \uhhhh:4个16位数字给定的十六进制码点的Unicode字符
  • \Uhhhhhhhh:8个32位数字给定的十六进制码点的Unicode字符
  • \xhh:2个8位数字给定的十六进制码点的Unicode字符

3)常用操作

  • a) 字符串连接:+
  • b) 关系运算符:>、>=、<、<=、==、!=
  • c) 赋值运算符:+=
  • d) 索引:s[index],针对只包含ascii字符的字符串
  • e) 切片:s[start:end] ,针对只包含 ascii 字符的字符串

例子:

package main

import "fmt"

func main() {
    //""=> 可解释
    // `` => 原生字符串
    // 特殊字符 \r \n \f \t \b \v
    var name string = "k\tk"
    var desc string = `我来\t自中国`

    fmt.Println(name)
    fmt.Println("k\\tk")

    fmt.Println(desc)

    // 操作
    // 算术运算符: +(连接)
    fmt.Println("我叫" + "tt")
    //关系运算(== != < <= > >=)
    fmt.Println("ab" == "bb")
    fmt.Println("ab" != "bb")
    fmt.Println("ab" < "bb")
    fmt.Println("ab" > "bb")
    fmt.Println("ab" <= "bb")
    fmt.Println("ab" >= "bb")
    fmt.Println("bb" >= "ba")
    fmt.Println("bb" >= "b")

    //赋值
    s := "我叫"
    s += "kk"
    fmt.Println(s)

    // 字符串定义内容必须只能为ascii
    // 索引 0 - n-1 (n 字符串的长度)
    desc = "abcdef"
    fmt.Printf("%T %c \n", desc[0], desc[0])
    fmt.Println(len(desc))

    //切片
    fmt.Printf("%T %s \n", desc[0:2], desc[0:2])

    desc = "我爱中国"
    fmt.Printf("%T %s \n", desc[0:2], desc[0:2])

    fmt.Println(len(desc))

}

 

4)常用函数

  • a. len:获取字符串长度(针对只包含ascii字符的字符串)
  • b. string: 将 byte 或 rune 数组转换为字符串
package main

import "fmt"

func main() {
    var msg = "我的名字\n是Jordan"
    var msgRaw = `我的名字\n是Jordan`
    fmt.Printf("%T %s\n", msg, msg)
    fmt.Printf("%T %s\n", msgRaw, msgRaw)

    //操作
    //字符串连接+
    fmt.Println(msg + msgRaw)

    //赋值 = +=
    msg += "----Jordan"
    fmt.Println(msg)

    //索引,切片,ascii
    msg = "abcdefg"
    fmt.Printf("%T %#v %c\n", msg[0], msg[0], msg[0])
    fmt.Println(msg[1:3])

    //len
    fmt.Println(len(msg))
    fmt.Println(len(msgRaw))
}

字符串遍历

Go语言支持两种方式遍历字符串。一种是以字节数组的方式遍历:

str := "Hello,世界"
n := len(str)
for i := 0; i < n; i++ {
  ch := str[i]    // 依据下标取字符串中的字符,类型为byte
  fmt.Println(i, ch)
}

这个例子的输出结果为:

    0 72
    1 101
    2 108
    3 108
    4 111
    5 44
    6 32
    7 228
    8 184
    9 150
    10 231
    11 149
    12 140

可以看出,这个字符串长度为13。尽管从直观上来说,这个字符串应该只有9个字符。这是 因为每个中文字符在UTF-8中占3个字节,而不是1个字节。

另一种是以Unicode字符遍历:

str := "Hello,世界"
for i, ch := range str {
    fmt.Println(i, ch)        //ch的类型为rune 
}

输出结果为:

    0 72
    1 101
    2 108
    3 108
    4 111
    5 44
    6 32
    7 19990
    10 30028

以Unicode字符方式遍历时,每个字符的类型是rune(早期的Go语言用int类型表示Unicode 字符),而不是byte。

5)占位符

使用 fmt.Printf 进行格式化参数输出,占位符: 

  • %s

6)常用包:

7.6 字符类型

字符类型在Go语言中支持两个字符类型,

  • 一个是byte(实际上是uint8的别名),代表UTF-8字符串的单个字节的值;
  • 另一个是rune,代表单个Unicode字符。

关于rune相关的操作,可查阅Go标准库的unicode包。另外unicode/utf8包也提供了UTF8和Unicode之间的转换。

出于简化语言的考虑,Go语言的多数API都假设字符串为UTF-8编码。尽管Unicode字符在标准库中有支持,但实际上较少使用。

7.7 数组

 

7.8 数组切片

 

7.9 map

 

 

 



   

 

posted @ 2020-04-09 21:25  康康路马  阅读(721)  评论(0编辑  收藏  举报