GO 程序设计

92 阅读11分钟

go 执行流程分析

.go 文件  -> (go build) 可执行文件 —》(运行) 结果、

.go -> (go run) ->结果

编译和运行

1、可以指定可运行的二进制文件

import "fmt"  fmt包中提供格式化、输入输出的函数

go 语言转义字符

1) \t 表示一个制表符,实现对齐功能;2) \n  表示换行符;3)\  转义符;4) \r  回车;  当前行的最前面开始输出

格式化

gofnt 格式化文件一行代码 不要超过80行

《变量》

1)声明变量 定义变量2)赋值3)使用

注意事项

1、表示内存一个存储区域2、第一种 指定变量类型 不指定值 则使用默认值第二种 根据值自行判断 数据类型(类型推导)第三种  省略var 使用:= 赋值  3、多变量声明var n1,n2,n3 intvar n1,name,n3,ss= 100,"小米",200,"丽江"var (var name intvar password  stringvar is boole)如何声明全局变量 在函数外声明就是全局变量package main​import (    "fmt"    "strings")var (    password=1)​func main() {    var (    // 定义 姓名    name string    id int    // 定义 密码    password int    )    // 赋值    name="小米"    //password=123456    id=1    isn:=true    password ++    fmt.Println(password+id,isn,name)    fmt.Println(strings.Compare(name,""))}1、该区域内的变量可以在同一类型范围内不断变化2、变量在同一作用域内不能同名3、变量=变量名+值+数据类型4、变量没有初赋值  编译器会给默认值int 默认为0  string 默认是空串

程序中+号使用

1)当两边都是数值 +号为加法2)当两边是字符串时 表示为字符串拼接

《数据类型》

基本类型  数值类型      int,int8,int16,int32,int64
                     uint,uint8 (无符合)
         浮点数    float32 float64
         字符型     byte
         布尔值    bool
         字符串    string
          run
派生/复杂类型 1、指钟
            2、数组
            3、结构体
            4、函数
            5、接口
            6、Map
            7、管道
            8、切片

一、整数

   类型   有无符号  占用存储空间  表数的值范围
1int81         -128~127
2int162         -2^15 ~ 2^15-1
3int324         -2^31 ~ 2^31-1
4int648         -2^64 ~ 2^64-1

无符号

  类型      有无符号     占用存储空间          表数范围
1uint81                0-255
2uint162                0-2^16-1
3uint324                0-2^32-1
4uint648                0-2^64-1            

其他类型

rune 用来处理中文字符

整型默认是int

保小不保大、不确定范围时,尽量采用大的范围

1byte=8bit

浮点类型(小数类型)

小数类型就是用于存放小数的 比如 1.2 、0.23

package main
import (
	"fmt"
)
func main() {
	var price float32 =89.12 
	fmt.Println("price",price)
}

小数类型 分类

类型                占用存储空间     表数范围
单精度(float32)        4           -3.403E38~ 3.403e3b
双精度(float64)        8           -1.79E308 ~ 1.79E308

package main
import (
	"fmt"
)
func main() {
	var price float32 =89.12 
	var num1 float64=-890000000002.1200000002
	fmt.Println("price",price,num1)
}

PS D:\del\GoPath\src\main> go run main.go
price 89.12 -8.9000000000212e+11

注意事项:

精度可能丢失 说明float64 比float32 要更加准确

说明,如果需要保存一个精度更加高的 需要使用 float64

os 操作系统

浮点数默认声明为float 64位的

package main

import (
	"fmt"
)

func main() {
	var price float32 =.12  // 等于 0.12
	var num1 float64=-890000000002.1200000002
	fmt.Println("price",price,num1)
}

package main
import (
	"fmt"
)
func main() {
	var price float32 =.12 
	var num1 float64=-890000000002.1200000002
	fmt.Println("price",price,num1)

	// 科学计数法
    var num2 =5.23e2
	fmt.Println("num2",num2)
}

三、字符类型

存储单个字符 一般使用byte来保存、GO的字符串是由字节组成的

package main

import (
	"fmt"
)
func main() {
   // 字节
   var c byte='a'
   var a byte='0'
   //我们直接输出byte 时,直接输出的字符的ASCII码值**
   fmt.Println("c",c)
   fmt.Println("a",a)
   //如果我们希望输出的对应的字符,需要使用格式化输出
   fmt.Printf("%c\n",a)
}

当我们直接输出byte 时,直接输出的字符的ASCII码值

如果需要输出值,需要格式化输出

GO的字符使用UTF-8 编码

英文字母是一个字节 汉字是三个字节

package main

import (
	"fmt"
)
func main() {
   // 字节
   var c byte='a'
   var a byte='0'
   //我们直接输出byte 时,直接输出的字符的ASCII码值**
   fmt.Println("c",c)
   fmt.Println("a",a)
   //如果我们希望输出的对应的字符,需要使用格式化输出
   fmt.Printf("%c\n",a)
   // 
   var c3 int=22232
   fmt.Printf("%c\n",c3)

   //字符类型进行计算,相当于一个整数 计算时按码值计算

   var n1=10+'a'
   fmt.Println("n1=",n1)
}

字符类型(char)

布尔类型

布尔类型 bool类型 bool类型只能是true或false

占一个字节

bool类型适用于逻辑运算

package main

import (
	"fmt"
	"unsafe"
)
func main() {
   // 布尔类型
   var a bool=true
   //bool 类型占用存储空间是1字节
   fmt.Println("a 的占用的空间",unsafe.Sizeof(a))
   // 2、bool类型只能取true 或者false 
   
}

《字符串类型:string》

package main

import (
	"fmt"
	"unsafe"
)
func main() {
   // 字符串类型
   var address string="北京长城 10KM "
   //string 类型占用存储空间是16字节
   fmt.Println("a 的占用的空间",unsafe.Sizeof(address))
   // 
	fmt.Println(address)
}

注意事项:

package main

import (
	"fmt"
	"unsafe"
)
func main() {
   // 字符串类型
   var address string="北京长城 10KM "
   //string 字符串使用UTF-8编码 
   fmt.Println("a 的占用的空间",unsafe.Sizeof(address))
   // 字符串一断赋值  不可变
   var str="hello"
   //str[0]='a'
	// 双引号  转义符会识别 
	// 反引号 以字符串的原生输出 包括换行和特殊字符 可以实现防止攻击
	// 输出源代码 或者其他的字符
	str="abc\nbc"
	fmt.Println(str)
    // 反引号  esc 键下面的
	str2:=` var address string="北京长城 10KM "
	//string 字符串使用UTF-8编码 
	fmt.Println("a 的占用的空间",unsafe.Sizeof(address))
	// 字符串一断赋值  不可变
	var str="hello"`
   fmt.Println("str2",str2)
}

package main

import (
	"fmt"
	"unsafe"
)
func main() {
   // 字符串类型
   var address string="北京长城 10KM "
   //string 字符串使用UTF-8编码 
   fmt.Println("a 的占用的空间",unsafe.Sizeof(address))
   // 字符串一断赋值  不可变
   var str="hello"
   //str[0]='a'
	// 双引号  转义符会识别 
	// 反引号 以字符串的原生输出 包括换行和特殊字符 可以实现防止攻击
	// 输出源代码 或者其他的字符
	str="abc\nbc"
	fmt.Println(str)
    // 反引号  esc 键下面的
	str2:=` var address string="北京长城 10KM "
	//string 字符串使用UTF-8编码 
	fmt.Println("a 的占用的空间",unsafe.Sizeof(address))
	// 字符串一断赋值  不可变
	var str="hello"`
   fmt.Println("str2",str2)
   //字符串的拼接方式
    var str3="Hello"+"world"
	str3 +="haha!"
	fmt.Println("str3",str3)
	//当一个字符串很长时, 可以分行写 + 号在最上一行
	var str4="Hello"+"world"+"Hello"+"world"+"Hello"+"world"+
	"Hello"+"world"
	fmt.Println("str4",str4)
}

基本数据类型默认值

package main

import (
	"fmt"
)
func main() {
   // 基本数据类型
   // int 默认值 0
   var str int
   // float  o
   var str1 float64
   // bool 类型  false
   var str2 bool
   // string 类型  默认是空串
   var str3 string
   fmt.Println("str",str)
   fmt.Println("str1",str1)
   fmt.Println("str2",str2)
   fmt.Println("str3",str3)
}

输出结果:PS D:\del\GoPath\src\main> go run main.go str 0 str1 0 str2 false str3

基本数据类型转换

go中 数据类型转换 不存在 自动转换 只能显式转换

package main

import (
	"fmt"
)
func main() {
   // 基本数据类型转换  不存在自动转换  显式转换
   var num int=100
   //T(v) T需要转换的类型 v需要转换的值
   var j=float32(num)
   var sum int8=int8(num)
   fmt.Println("num",j)
   fmt.Println("sum",sum)
}

注意事项

1、类型转换 转换的只是数据的值,变量本身的数据没有发生变化

2、超过范围后,只是转换的结果按溢出处理,

package main

import (
	"fmt"
)
func main() {
   // 基本数据类型转换  不存在自动转换  显式转换
   var num int=100
   //T(v) T需要转换的类型 v需要转换的值
   var j=float32(num)
   var sum int8=int8(num)
   fmt.Println("num",j)
   fmt.Println("sum",sum)
   //被转换的数据 只是数据的值 变量本身的值并没有变化
   fmt.Printf("%T",num)
   // 只是转换的结果按溢出处理,
   var num2 int64=999999
   var num3 int8=int8(num2)
   fmt.Println("num3",num3)
}

package main

import (
	"fmt"
)
func main() {
   // 基本数据类型转换  不存在自动转换  显式转换
   var n1 int32=12
   var n2 int64
   var n3 int8
   n3=int8(n1)+20  // int32 => int64
   n2=int64(n1)+20   // int 32 => int64
   fmt.Println("n2",n2)
   fmt.Println("n3",n3)
}

基本数据类型转换string 类型

1、将基本数据类型转换为string类型

%d  十进制输出
%b  二进制输出
%T  布尔

package main

import (
	"fmt"
	"strconv"
)
func main() {
   //基本数据类型转换为string 类型
   var num int=100
   var sex bool=true
   var num2 float64=23.678

   // fmt.Sprintf()   基本数据转换为sting类型
   var num1=fmt.Sprintf("%d",num)
   var num3=fmt.Sprintf("%T",sex)
   var num4=fmt.Sprintf("%%",num2)
  fmt.Println("num1",num1)
  fmt.Println("num3",num3)
  fmt.Println("num4",num4)
  //strconv 转换
   var num5=strconv.FormatInt(int64(num),10)
   fmt.Println("num5",num5)
   // strconv.FormatFloat(num2,'f',10,64)
   // 'f' 格式  10 表示小数位保留10位  这个小数是float64的
   var num6=strconv.FormatFloat(num2,'f',10,64)
   fmt.Println("num6",num6)
   var num7=strconv.FormatBool(sex)
   fmt.Println("num7",num7)
    // Itoa 函数
   var num9=strconv.Itoa(num2)
}

《string 类型转换为基本数据类型》

package main

import (
	"fmt"
	"strconv"
)
func main() {
   //string 转换为基本数据类型
   var sex string="true"
   var age string="27"
   var meonny string="23.333"
   //var strngbool,_=strconv.ParseBool(sex) 
   // 函数本身会返回两个值 (valus bool ,err error)
   // 因为不想获取后面的值 只关心前面的值
   //   ,_ 忽略后面的值
   var strngbool,_=strconv.ParseBool(sex)

   //字符串转换为int 类型
   //var stringint,_=strconv.ParseInt(age,10,8)
   // age 需要转换的值
   // 10 进制  十进制
   //  0 int    8  int8   16 int16  64 int64
   var stringint,_=strconv.ParseInt(age,10,8)

   // 字符串转换为浮点数
   //
   var stringfloat,_=strconv.ParseFloat(meonny,64)
   fmt.Println("strngbool",strngbool)
   fmt.Println("stringint",stringint)
   fmt.Println("stringfloat",stringfloat) 
}

注意事项

二、指针

指针1、基本数据类型,变量存的就是值,也叫值类型

2、获取变量的地址,用&i,来获取变量的地址

3、指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值

package main

import (
	"fmt"
	_"strconv"
)
func main() {
   //指针类型
   // 基本数据类型在内存布局
   var i int=10
   // i 的地址是什么 ,&i 获取变量的地址
   fmt.Println("i 的地址:",&i)
   //指针类型
   // 1、par 是一个指针变量
   // 2、par的类型是 *int
   // 3、par 本身的值是 &i
   var par *int=&i
   fmt.Println("指针par",par,&par)
   //获取指针类型的值  *变量
   *par++
   fmt.Println("指针par的值",*par)
   *&i++  // =======*&i 指向地址===
   fmt.Println("套",*&i)
}

指针类型注意事项:

package main

import (
	"fmt"
	_"strconv"
)
func main() {
   //指针类型
   //将num 的值
   var num int=100
   var par *int=&num
   // par 访问的是num的存储空间  修改存储空间的值 影响num变量存储的值
   *par=200
   *par++
   fmt.Println("par",*par)
   fmt.Println("par",num)
}

值类型:基本数据类型 int系列、float系列、数组、bool、string、结构体

引用类型:指针、slice切片、map、管道chan、interface等都是引用类型

值类型:变量直接存储值,内存通常在栈中分配

引用类型,变量存储的是一个地址,这个地址对应的空间才真正存储数据的,内存通常是堆区上分配,当没有任何变量引用这个地址,该地址对应的数据空间就成为一个垃圾,由GC来回收。

栈区:值类型数据,通常是在栈区

堆区:引用类型,通常在堆区分配空间

《标识符》

严格区分大小写、不能包含空格、下划线_是go中一个特殊的标识符,可以代表其他任何的标识符,但是它对应的值会被忽略,所以只能作为占位符使用

package main

import (
	"fmt"
	_"strconv"
)
func main() {
   //标识符
   // _ 只能作为占位符 不能作为标识符使用
   var _ int=100
   fmt.Println("par")
}

系统保留关键字 一共25个

break、default、func、interface、select、case、

defer、go、map、struct、chan、else、goto、package、

switch、const、fallthrough、if、range、type、continue、

for、import、return、var

如果变量名、函数名、常量名首字母大写,则可以被其他的包访问,如果首字母小写,则只能在本包中使用(大写是公有、小写是私有)

《二、运算符》

1、算术运算符

package main

import (
	"fmt"
)
func main() {
   //算术运算符
   // + 正号
   
   // %取模
   var n1 int=10
   var n2 int=3
   var n3 =n1%n2
   fmt.Println("取模",n3)
   // / 除法
   // 如果除的两头是整数 , 则结果是整数
   var n4=n1 /n2 
   // n4 33
   var n5 float32=10/4
   fmt.Println("除法",n4)
   fmt.Println("除法",n5)
   // 如果希望保留小数部分,则需要有浮点数参与运算
   var n6=10.0/3
   // n6 2.5
   fmt.Println("除法",n6)
}

结果:

取模:

package main

import (
	"fmt"
)
func main() {
   //算术运算符 
   // %取模
   // 公式:a % b= a- a / b * b
   fmt.Println("10%3",10%3)
   fmt.Println("-10%3",-10%3)
   fmt.Println("10%-3",10%-3)
   fmt.Println("-10%-3",-10%-3)
}

结果:

Go 自增和自减只能当成一个独立使用

package main

import (
	"fmt"
)
func main() {
   //算术运算符 
   // ++ 和 -- 
   var m int=10
   m++  // i=i+1
   fmt.Println("m:",m)
   m--  // i=i-1
   fmt.Println("m:",m)
   // 注意事项  ++ 和-- 只能独立使用
   var i int
   //i=m-- //错误  m-- 只能独立使用
   //i=m++ //错误  m++  只能独立使用  没有前-- 前++ 
   fmt.Println("i",i)
}

2、赋值运算符

1)赋值运算符的计算顺序是从右向左

2)赋值运算符的左边 只能是变量 右边可以是变量、表达式、常量值

表达式:任何有值的都可以看成表达式

package main

import (
	"fmt"
)
func main() {
   //赋值运算符
   // 交换两个值,不使用第三方变量
   var age int=50
   var b int=40
   age=age+b
   b=age-b
   age=age-b
   fmt.Println("age", age)
   fmt.Println("b", b)
   // +=  加 后赋值
   // /=   除 后赋值
   // %=   取模后赋值
   // -=   减 后赋值
}

3、比较运算符/关系运算符

package main

import (
	"fmt"
)
func main() {
   //关系运算符
   var n1 int=9
   var n2 int=8
   fmt.Println(n1==n2)
   fmt.Println(n1!=n2)
   fmt.Println(n1>n2)
   fmt.Println(n1<n2)
   fmt.Println(n1>=n2)
   fmt.Println(n1<=n2)
}

4、逻辑运算符

package main

import (
	"fmt"
)
func main() {
   //逻辑运算符
   var n1 bool=true
   var n2 bool=false
   fmt.Println(n1&&n2)
   fmt.Println(n1!=n2)
   fmt.Println(n1||n2)
   fmt.Println(!n1)
   var age int=30
   if age>35&&age<=65 {
      fmt.Println("已退休")
   }
   if age<=35 {
      fmt.Println("没有退休")
   }
}

注意事项

&& 也叫短路与 || 也叫短路或

package main

import (
	"fmt"
)
func main() {
   //逻辑运算符
   var age int=40
   if age<=35 && tset() {
      fmt.Println("没有退休")
   }else {
      fmt.Println("我出现了。。。。。")
   }
}
func tset() bool{
   fmt.Println("tses...")
   return false
}

运算符的优先级

只有单目运算符、赋值运算符是从右向左运算的

() ++ -- -> 单目 -> 算术运算符 -> 移位 -> 关系运算符 -> 位运算符 -> 逻辑运算符 -> 赋值运算符 -> 逗号

5、位运算符

在go中 二进制 不能表示一个数

二进制转 八进制

6、其他运算符