软件下载
https://golang.google.cn/ https://dl.google.com/go/go1.20.5.windows-amd64.msi
环境变量配置
我的电脑--属性--环境变量-用户环境变量 添加一下 GOWKS=G:\tpf\gowks GOROOT=%GOWKS%\app\gowin GOBIN=%GOWKS%\bin GOPATH=%GOWKS% 将下面的路径添加到path中 %GOROOT%\bin %GOBIN%
软件下载
https://dl.google.com/go/go1.19.3.linux-amd64.tar.gz https://studygolang.com/dl/golang/go1.18.10.linux-amd64.tar.gz https://golang.google.cn/
Go环境变量设置
export GOWKS=/opt/wks/gowks export GOROOT=$GOWKS/app/go export GOBIN=$GOWKS/bin export GOPATH=$GOWKS export PATH=$GOROOT/bin:$GOBIN:$PATH GOWKS是自定义的GO工作空间, GO软件安装在其app/go目录下, GOWKS同时也是GOPATH, 这里面包含项目运行的GO软件,下载的依赖包,编辑后的命令,说明文档等一切项目相关的文件。 后续若进行项目迁移,不管是GO本身版本变化,还是它的依赖包版本变化, 直接将这个目录COPY走就解决了所有问题。 GO ENV go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct # 国内七牛云提供
go mod
mkdir esql cd esql go mod init 就完成go mod的初始化化了 go mod tidy 这一步自动将go文件引入的外部包写入mod文件,并修改sum文件 如果要使用或找不到本地包,则修改mod相应的包指向本地目录位置 require gitee.com/ol v0.0.0-00010101000000-000000000000 // indirect replace gitee.com/ol => ../../ol
go vendor
进入包目录,执行 go mod vendor 就可以将依赖的外部包打包一份到vendor目录下,repalce指向本地的除外 这里要求你的项目放在GOPATH/src目录下 依赖于GOPATH,可放于GOPATH/src目录下,或者GOPATH/src的项目目录下 查找顺序:从当前模块目录找vendor目录,一直找到GOPATH/src 使用:手动依赖包或自己写的模块放到vendor目录,或者mod模式下进入目录执行go mod vendor 好处:下载的依赖包随项目走,不用关心这些依赖包的版本变化导致项目不可用了 注意事项 go vendor是要放在gopath/src目录下的 如果gopath/src/vendor与gopath/src下存在相同的模块,则vendor目录的优先级高, 即会调用vendor下的模块 而go mod的模块目录如果使用replace指定特定目录后,就不会走vendor了 如果使用go mod编辑报错同时又是个人项目,可以关闭go mod:go env -w GO111MODULE=off 没了go mod的自动下载,就将手工将下载的依赖包放到vendor下, 项目迁移时,vendor随之迁移,这样的项目也是极其稳定的, 或者像文章开始那样搭建项目,项目相关所有文件都放在$GOWKS目录下, 迁移时,GO版本与其依赖包都不变化,这样就万无一失了。 如果没有使用go mod,那么下载并编辑项目github.com/kardianos/govendor,生成一个govendor go get -u -v github.com/kardianos/govendor go mod init go mod tidy go build govendor用法 govendor init 初始化vendor目录 govendor add +external 添加外部依赖 govendor update +external 更新外部依赖 govendor update $PACKAGE_NAME 更新指定包的依赖
export GOWKS=/opt/tpf/liu export GOROOT=$GOWKS/app/go export GOBIN=$GOWKS/bin export GOPATH=$GOWKS export PATH=$GOROOT/bin:$GOBIN:$PATH
go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct # 国内七牛云提供
GO有四种数据类型,数字、布尔、字符、派生类型;这里使用 前三种 简单类型 来说明变量的定义与使用
int8/uint8 int16/uint16 int32/uint32 int64/uint64 float32 float64 complex64 bool byte rune :32位有符号整型,存储Unicode字符 int/uint :是32位还是64位看平台,其他的通过名字就能看到多少位 uint8 0-255,int8则是-128-127,这两个是Go的最小长度类型,其他类型在内存中分配的长度都要比这两个大; -------------------------------------------- package main import "fmt" var ( aa = 1 bb = true ss = "作用域为包的变量" s2,s3 = "包变量的位置可能写在包内的任何地方","即可以是引用的前面也可以在引用的后面" ) //GO有四种类型,数字、布尔、字符、派生类型 //变量的默认值 func var1(){ var a int var b bool var f float64 var s string // %d 表示数字,%s表示字符串,%q可以为字符串带上双引号 fmt.Printf("%d-%s-%q\n",a,s,s) // 0--"" fmt.Println(b) //false fmt.Println(f) //0 } //变量初始化 func var2(){ var a int = 100 //明确地写出了变量的类型 var b,f,s = true,3.14,"批评别人时,一定要顾及听者的面子" //不定义类型,同时多变量写于一行 fmt.Println(a,b,f,s) var aa = 300 var ss = "在回答别人或对别人发表观点时,一定要先准确理解别人的意思" fmt.Println(aa,ss) } //较常用的变量声明赋值方式 func var3(){ //多行合并为一行,省去了类型,连var关键字也省去了,编辑器自动判断变量类型;只能用于一次声明变量时使用 s1,s2 := "话越多","越没有份量" fmt.Println(s1,s2) //第二次使用时,不可再加冒号 s1,s2 = "讲话时不能只顾着自己说","更要注意对方的感受和情绪变化" fmt.Printf("%s,%q",s1,s2) //讲话时不能只顾着自己说,"更要注意对方的感受和情绪变化" } func main() { var1() var2() var3() }
root@kl:/opt/wks/gowks/src/cmd# dcService -c /etc/dc.cnf dcService: /usr/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by dcService) dcService: /usr/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by dcService) # ldd --version ldd (Ubuntu GLIBC 2.31-0ubuntu9.7) 2.31 # gcc -dumpversion 9 当初build时的glibc版本高于现在运行的 所以,build的glibc版本不要太高,不要高于使用者的glibc版本 |
|
|
|
|
变量的命名: 推荐使用studentName,而不是student_name 首字母大写有特殊的含义,比如一个包的方法要想在其他包中使用,那么该方法名称必须首字母大写,又比如结构体中的属性等 变量的作用域: 比如包a下有b.go与c.go,b.go中有方法C,则其他包引用的方式为a.C() 包,即文件所在目录的名称,包名文件夹下可以有多个文件,包内变量的作用域是可以跨越这些文件的; 比如,一个包中不允许存在两个相同名称的方法,会提示重复; 函数内的变量的作用域就只是在函数内了 字符串 字符串分为原生字符串、解释型字符串两种; 原生字符串使用``(反引号),解释型字符串使用双引号"",解释型字符串中可以解析转义字符;
package main import ( "fmt" "math" ) //常量 func cons(){ const a,b= 3,4 //常量的数字在不明确指定类型的情况下,即可以作为int使用,也可以作为float32/float64使用 var c int c = int(math.Sqrt(a*a+b*b)) //不需要转float64 fmt.Println(c) //5 const aa,bb int = 3,4 cc := math.Sqrt(float64(aa*aa + bb*bb)) fmt.Println(cc) //5 fmt.Println(s1,s2) //你多少次在讲话前 没有去在意对方的心思 } //包内常量,go的常量通常不全部大写表示,这是因为go语言定义的变量或常量,首字母大写是有特定含义的 const ( s1,s2 ="你多少次在讲话前","没有去在意对方的心思" ) //枚举 func enum(){ //在go中可以简单地使用const常量来表示枚举 const( java = 0 net = 1 c =2 rust = 3 ) const( aa = iota //一个行计数器,从0开始,刚好与枚举从零开始相符,故而使用iota简化枚举的写法 bb _ //_一个占位符,这样下面的dd才能被赋值3 dd ) const( byte = 1 <<(10 * iota) kb mb gb tb pb ) fmt.Println(byte,kb,mb,gb,tb,pb) //1 1024 1048576 1073741824 1099511627776 1125899906842624 } func main() { cons() enum() }
数组
var arr1 = [4]uint8{192,168,0,1} var arr2 = [...]uint8{192,168,0,2} ...,三个小黑点,由Go编译器计算该值的元素数量并以此获得其长度,也适用于函数参数
切片
var slic1= []string{"192.168.0.1","192.168.0.2"} var slic2=append(slic1,"192.168.0.3") var slic3=make([]string,50) append可以为切片类型[]string追加元素 make可以高效地为一个切片初始化数据,make([]string,50)则是一次性初始化50个默认值为""的元素
len与cap
func main(){ println(len(arr1),cap(arr2),len(slic2),cap(slic3)) } 输出 4 4 3 50
package main var m1 = map[string]bool{} func main(){ m1["魔镜,我是世界上最美的女人吗"]= false println(m1["魔镜,我是世界上最美的女人吗"]) println(len(m1)) delete(m1,"魔镜,我是世界上最美的女人吗") println(len(m1)) delete(m1,"魔镜,我是世界上最美的女人吗") println(len(m1)) } delete可以删除本身就不存在的元素,输出 false 1 0 0 相比数组的定义, map多了关键字map, 以及key的类型,放在了中括号里 map[key type]value type{}
for循环
for i:= 0;i<9;i++ { fmt.Println(i) }
for循环数组
for index, val := range arr{ fmt.Printf("第 %d 位 x 的值 = %d\n", index, val) }
for循环map
for key, value := range oldMap { newMap[key] = value }
for 永远循环,死循环中通常会有跳出循环的条件
for { record, err := r.Read() if err == io.EOF { break } if err != nil { log.Fatal(err) } for i:= 0;i<r.FieldsPerRecord;i++ { fmt.Println(i,record[i]) } }
if 条件语句
package main import ( "fmt" "io/ioutil" ) func if1(){ const filename = "/tmp/a.log" if txt, err := ioutil.ReadFile(filename); err != nil { fmt.Println(err) } else { fmt.Printf("%s\n", txt) } }
go switch: 找到第1个条件成立的分支就返回
package main import ( "fmt" ) func switch1(level int) string{ res := "" switch level{ case 1: res = "100000" case 2: res = "30000" case 3: res = "10000" default: res = "1000" } return res } func switch2(level int) string{ res := "" switch { case level == 100: res = "100000" case level > 90: res = "30000" case level > 80: res = "10000" case level > 60: res = "1000" case level <= 60: panic("You ......") } return res } func main() { res := switch1(1) println(res) //100000 fmt.Println(switch1(1),switch1(2)) // 100000 30000 fmt.Println(switch2(100),switch2(88)) // 100000 10000 //下面这个是直接报错,并不会输出前两个到第三个时再报错 fmt.Println(switch2(100),switch2(88),switch2(38)) }
结构体定义示例
变量 : var name 数据类型 常量 : const name 数据类型 结构体: type name 数据类型 --> type Student struct 从上面三行感受一下GO语言变量设计的风格: 第一个关键词 表示要定义的事物属于哪个大类,是变量,还是常量,还是本身就是一个类型 第二个关键词 表示要定义的事物的名称 第三个关键词 表示细分的数据类型,是简单类型数字,还是复合类型 字符串,结构体等 package main import ( "fmt" ) type Student struct { id int name string } func (st *Student) ShowName(){ st.name = "花开12瓣,瓣瓣为一生" fmt.Println(st.name) } func main(){ s1 := Student{} s1.ShowName() }
常用格式化输出
package main import ( "fmt" ) func main(){ fmt.Println("我来人间一趟") fmt.Printf("%s\n","本来无念无想") ss := fmt.Sprintf("%v","一入红尘就变了模样") println(ss) } %d 表示十进制 %e 科学计数法,例如 -1.4e+11 %f 小数点 %o 表示八进制 %s 字符串表示(string类型或[]byte) %p 十六进制内存地址,前缀ox %v 通用格式,按数据本身的类型输出,比如是字符串,此时%v自动转为%s的效果 package main import ( "fmt" ) type Student struct { id int name string } func main(){ s1 := Student{id:1,name:"韩立"} fmt.Printf("%v\n",s1) // {1 韩立} fmt.Printf("%+v\n",s1) // {id:1 name:韩立} fmt.Printf("%#v\n",s1) // main.Student{id:1, name:"韩立"} fmt.Printf("%T\n",s1) // main.Student }
数字之间及字符串的转化
package main import ( "fmt" "reflect" "strconv" ) func main() { //查看一个数据的类型 fmt.Println(reflect.TypeOf("123")) // string fmt.Println(reflect.TypeOf(1.23)) // float64 strconv.Atoi("123") // 字符串转数字 strconv.Itoa(123) // 数字转字符串 strconv.FormatUint(uint64(123), 8) // 10进制转8进制 strconv.FormatUint(uint64(123), 16)// 10进制转16进制 strconv.FormatFloat(float64(1.23), 'e', 4, 32) //10进制转float32,保留4位有效数字,e表示科学计算法 strconv.FormatFloat(1.23, 'f', 4, 64) //10进制转float64,保留4位有效数字,f表示浮点数 }
依赖库
github.com/godror/godror database/sql
客户端安装
oracle客户端,instantclient-basic-linux.x64-11.2.0.4.0.zip rpm -qa | grep libaio yum install libaio 动态库设置: sudo sh -c "echo /opt/app/instantclient_11_2 > /etc/ld.so.conf.d/oracle-instantclient.conf" sudo ldconfig $ cat /etc/ld.so.conf.d/oracle-instantclient.conf /opt/app/instantclient_11_2
oracle客户端下载-夸克网盘