Go语言基础(一)

一、Go语言简介

Go即Golang,是Google公司2009年11月正式对外公开的一门语言
Go是静态强类型语言,是区别于解析型语言的编译型语言。
解析型语言--源代码是先翻译为中间代码,然后解析器对代码进行解释执行。
编译型语言--源代码译生成机器语言,然后由机器直接执行机器码即可执行。

二、Go语言特性

跨平台的编译型语言
语法接近C语言
管道,切片,高并发
有垃圾回收机制
支持面向对象和面向过程的编程模式

Go语言用途:区块链(最开始的开源的数字货币是用Go写的)、docker/k8s

三、Go语言目录架构

GOPATH的工作区包含bin、src、pkg
src---源码(包含第三方的和自己项目的)
bin---编译生成的可执行程序
pkg---编译时生成的对象文件

四、Go语言开发环境搭建

IDEs下载地址:https://www.jetbrains.com/go/
安装包下载地址:https://golang.google.cn/dl/
windows和linux环境都可以进行安装,都需要添加环境变量,windows安装包有自动添加功能

了解ide:

-eclipse/myeclipse
-idea:做java开发
-pycharm:python开发
-goland:go语言开发
-vscode:go开发
-androidstudio开发:idea改的
-eclipse+adt

测试Hello World:

package main
import "fmt"

func main() {
    fmt.Println("Hello World")
}

打开cmd,到对应项目的目录下,执行命令
go build s1.go ---> 可以编译生成出s1.exe,然后执行就可以打印出:helloworld
也可以在IDEs里执行,和命令里执行差不多,只是没有生成s1.exe
并不是所有的go程序都可以编译成可执行文件,要生成可执行文件需要满足2个条件:
  --该go程序需要属于main包
  --在main包中必须还得包含main函数

Go程序的入口就是 main.main
go run可以将go build 2步并成一步且不生成exe文件
C:\代码\代码\src\day01>go run s1.go
hellowrold

五、Go命令介绍

基本命令介绍:
build:编译包和依赖
clean:移除对象文件
doc:显示包或者符号的文档
env:打印go的环境信息
bug:启动错误报告
fix:运行gofmt进行格式化
generate:从processing source生成go文件
get:下载并安装包和依赖
install:编译并安装包依赖
list:列出包
run:编译并运行go程序
test:运行测试
tool:运行go提供的工具
version:显示go的版本
vet:运行go tool vet

get命令:下载并安装第三方包

使用方式:go get 包名

然后我们可以用下面的方式进行使用
package main
improt "github.com/astaxie/beego" # 这里需要使用src下的完整路径
fun main(){
    beego.Run()
}

六、简述hello world程序

//单行注释
/*
多行注释
多行注释
 */
//表示是main包,表示程序入口
//程序执行,会去执行main包下的main函数
package main
//导入fmt包
import "fmt"

//main函数
func main()  {
    //使用fmt包下的Println打印
    //字符串用双引号
    fmt.Println("hellowrold")
}
package main 定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。

import "fmt" 告诉 Go 编译器这个程序需要使用 fmt 包

func main() 是程序开始执行的函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。

/*...*/ 是注释,在程序执行时将被忽略。单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。
多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾,且不可以嵌套使用,多行注释一般用于包的文档描述或注释成块的代码片段。 fmt.Println(...) 可以将字符串输出到控制台,并在最后自动增加换行字符 \n。 Print 和 Println 这两个函数也支持使用变量,如:fmt.Println(arr)。如果没有特别指定,它们会以默认的打印格式将变量 arr 输出到控制台。

 七、变量定义

# 定义单个变量
package main

func main() {
    //变量定义
    //第一种方式
    //var关键字 变量名 变量类型 = 变量值
    //变量定义了一定要使用,不使用报错
    var a int=10
    fmt.Println(a)
        //第二种方式(类型推导,省略类型)
        var b =10
        fmt.Println(b)
        //第三种(简略赋值) 用的最多
        c:=10
        fmt.Println(c)
}
// 定义多个变量
package main
import "fmt"

func main() {
    var a,b int
    a =10
    b =20
    fmt.Println(a,b)
}
或
func main(){
    //简略赋值声明多个(变量只能定义一次)
    a,b:=10,"lqz"
    fmt.Println(a,b) //10 lqz
}
或
func main(){
    //go是强类型语言(类型一旦确定,不能改变)
    var a int
    a = 11
    a = "test"
    fmt.Println(a)  //报错,int改为了string
}

八、变量类型

package main
import "fmt"

func main() {
    //布尔
    //var a bool =true
    //fmt.Println(a)
    //数字类型
    //var a int8=100
    //范围2的7次方-1
    //计算机最小单位:bit
    //字节:8个比特位
    //fmt.Println(a)
    //类型推导:
    //a:=10     //int  在32位机器上是int32 在64位机器是int64
    //var a uint64=10   //只表示正整数
    //可以表示小数
    //var a float32=19.08
    //fmt.Println(a)
    //byte:uint8的别名
    //var a byte =-10
    //rune: int32的别名
    //字符串(双引号)
    var a string ="lqz"
    fmt.Println(a)
}

九、常量

常量用来表示固定的值,不变的量

// 定义方法
package main

func main() {
    //定义常量
    //const关键字 变量名  = 变量值
    const age  = 10
    const  name = "lqz"
    //name="egon"
    const  name, age = "lqz",18
    //var  a,b  = "lqz",10
}

十、函数

语法:
//func关键字 函数名(变量 变量类型,变量 变量类型){
// }

// 1)位置传参
package main
import "fmt"

func main() {
    // 没有指定道姓传参,只能按位置传参
    test(1,2)
}

func test(a,b int) {
    fmt.Println(a+b)
}

// 2)返回值
//func关键字 函数名(变量 变量类型,变量 变量类型)返回值类型{}
func main() {
    // 返回值接收
    c :=test(1,2)
    fmt.Println(c)
}

func test(a,b int) int {
    return a+b
}

// 3)多返回值
func main() {
    // 返回值接收,必须是2个接收
    v,k:=test(1,2,"计算")
        // 如果有一个值不需要可以用_ 代替
    fmt.Println(v,k)
}

func test(a,b int,c string) (int,string) {
    return a+b,"计算成功"
}

// 4) 可变长传参
func main() {
    test(1,2,3)   //[1 2 3]  类似python中的列表,可切片

}
// ...可变长类型必须一样
func test(a ...int) {
    fmt.Println(a)
        fmt.Print(a[0])
}

十一、闭包

// 闭包:1.定义在函数内部;2.对外部作用于有引用
// 补充: 匿名函数 func (参数)(返回值){}

// 推导解释
func test()(func()(int,string)){
    a:=10
    // 匿名函数:省略函数名字,变灰的意思是可以省略
       //当成变量返回
    //var b func()(int)=func ()(int){
    //    fmt.Println(a)
    //    return 1
    //}
    b:= func()(int,string) {
        fmt.Println(a)
        return 1,";xxxx"
    }
    return b
}
// 
// func(d int)(int) 返回值
func test()(func(d int)(int),int){
    c:=func (d int)(int){
        fmt.Println("xxxx")
        return 1
    }
    return c,1
}

// 整体
func main() {
    k:=test(3)
    k(5)
}

// func(d int)(int) 返回值
func test(c int)(func(d int)()){
    a:=func (d int){
        fmt.Println(d+c)
    }
    return a
}

// 默认返回值
func test()( a,b int)  {
    return a,b
}
// int默认空值是0,string类型默认空值是""一行空

函数格式:func 名字(参数1 类型,参数2 类型)(返回类型,返回类型){}

十二、包管理

导入别的包:(与自己的包目录级别一样)
有严格的路径模式,如果是下载的模块放到了GoPath路径下 package main import
"mypackage" func main() { mypackage.Test() }

十三、if...else..

package main
import "fmt"

func main() {
    a:=11;
    //大括号必须和条件在一行
    if a<10{
        fmt.Println("<10");
    }else if a>10{
        fmt.Println(">10");
    }else {
        fmt.Println("10")
    }
}

package main
import "fmt"

func main() {
a:=11;
//大括号必须和条件在一行
if a<10{
fmt.Println("<10");
}else if a>10{
fmt.Println(">10");
}else {
fmt.Println("10")
}
}
注意:条件和{必须在一行

十四、for循环(GO中只有这种)

// 语法
////for 循环
//for 第一部分;第二部分;第三部分{
//}
func main(){
        //基本写法
    for i:=0;i<100;i++{
        fmt.Println(i)
    }

}
//其他用法1 省略第一部分
i:=0
for ;i<100;i++{
    fmt.Println(i)
}
//其他用法二 省略第三部分
i:=0
for ;i<100;{
    i=i+1
    fmt.Println(i)
}
//其他用法三 省略第二部分
for ;;{
    fmt.Println("xxx")
}
//更多使用
//for a<10  表示写在第二个位置
a:=0
for a<10{
    fmt.Println(a)
}
//死循环
for {
    fmt.Println("xxx")
    break //不加这个就不会跳出
}
//break 和continue
for i:=0;i<10 ;  i++{
    if i==5{
        //continue
        break
    }
    fmt.Println(i)
}

十五、switch...case条件语句

package main
import "fmt"
//单条件
func main() {
    a := 5
    switch a {
    case 1:
        fmt.Println("1")
    case 2:
        fmt.Println("2")
    case 4:
        fmt.Println("4")
        default:
                fmt.Println("不匹配")
    }
}
//多条件
    a := 4
    switch a {
    case 1,2:
        fmt.Println("1")
    case 3,6:
        fmt.Println("2")
    default:
        fmt.Println("不匹配")
    case 4:
        fmt.Println("4")
    }

//fallthrough 穿透:直接打印下一条
    a := 4
    switch a {
    case 1, 2:
        fmt.Println("1")
    case 3, 6:
        fmt.Println("2")
    case 4:
        fmt.Println("4")
        fallthrough //穿透
    case 5:
        fmt.Println("5")
        fallthrough
    default:
        fmt.Println("不匹配")
        fmt.Println("xxxxx")
    
    }
 //fallthrough 结果:
4
5
不匹配
xxxxx

十六、数组

package main
import "fmt"

func main() {
    //基本定义/定义并初始化
    //a[3]int:a数组的长度为3,数组内的类型都为int
    //var a [3]int=[3]int{1,2,3}
    //var a =[3]int{1,2,3}
    a:=[3]int{1,2,3}
    fmt.Println(a)
}
--------------------------------------------------------------------------------
//指定位置初始化
a:=[10]string{9:"lqz",8:"xxx"}
fmt.Println(a)
//结果[        xxx lqz]

//数组使用
var a [3]int=[3]int{1,2,3}
//--修改第0个位置的值
a[0]=100
var b int=a[2]  //赋值成变量
fmt.Println(a)
//结果:[100 2 3]

//数组的长度,开始可以忽略
// ... 的使用(少用)
a :=[...]int{9:1}  // 第九个位置赋值为1
fmt.Println(a)  //[0 0 0 0 0 0 0 0 0 1] 
fmt.Println(len(a))   //10

//数组的大小是类型的一部分:参数和返回值都是类型的一部分
a:=[3]int{1,2,3}
b:=[3]int{1,2,3}  //长度必须是一样,类型必须一样
b=a
fmt.Println(b)

//函数
a:=[3]int{1,2,3}
fmt.Println(a)
test(a)
fmt.Println(a)
//test(a)放在main外调用
func test(a [3]int)  {
    a[1]=1000
    fmt.Println(a)
}
//结果:
[1 2 3]
[1 1000 3]
[1 2 3]
-------------------------------------------------------------------------------
//数组迭代
a:=[3]int{1,2,3}
for i:=0;i<len(a);i++{
    fmt.Println(a[i])
}
//第二种方式(常见)
//range :python中range函数
// 关键字
//range 可迭代   如果用一个值接收:就是索引  如果用两个值接收:就是索引和值
for i,v:=range a{
    //fmt.Println(i)
    fmt.Println(a[i])
    fmt.Println(v)
}
--------------------------------------------------------------------------------
//多维数组
//定义一个二位数组
var a [5][3]int=[5][3]int{{1,2,3},{4,4,4}}
fmt.Println(a)
//结果:[[1 2 3] [4 4 4] [0 0 0] [0 0 0] [0 0 0]]
修改:var a [5][3]int=[5][3]int{2:{4,4,4}}
//循环
for i := 0; i < len(a); i++ {
    for j := 0; j < len(a[i]); j++ {
        fmt.Println(a[i][j])
    }
}
for _,v:=range a{
    for _,v1:=range v{
        fmt.Println(v1)
    }
}

十七、切片

解决数组追加值

package main
import "fmt"

func main() {
    //切片定义
    //切片底层基于数组
    a:=[9]int{1,2,43}
    fmt.Println(a) //[1 2 43 0 0 0 0 0 0]
    b:=a[1:3]
    fmt.Println(b)  //[2 43]
    //b[0]=100
    a[1]=999
    fmt.Println(b)   //[999 43]
    fmt.Println(a)   //[1 999 43 0 0 0 0 0 0]
}
package main
import "fmt"

func main(){
    a:=[5]int{1,2,43,0,0}
    b:=a[1:3]
    fmt.Println(b)  //[2 43]
    fmt.Println(len(b)) //2
    //切片追加值
        b=append(b,10)
    b=append(b,11)
    b=append(b,12)
    fmt.Println(b)  //[2 43 10 11 12]

}

# 查看切片容量
//查看切片的容量/长度
a:=[5]int{1,2,43,0,0}
b:=a[1:3]
fmt.Println(len(b))   //2
////查看容量
fmt.Println(cap(b))   //4
b=append(b,10)
b=append(b,11)
b=append(b,12)
fmt.Println(len(b))  //5
//查看容量(容量如果不够了,每次都会翻倍)
fmt.Println(cap(b)) //8
//切片第二种定义方式 中括号内不写东西,就是切片类型
//切片的空是nil
//通过make函数来完成初始化  第一个5是长度,第二个5是容量
func main(){
    var a []int=make([]int,5,5)
    if a==nil{
    fmt.Println("xxxx")
    }
    fmt.Println(len(a))  //5
    fmt.Println(cap(a)) //5
}

//切片是什么类型  是引用类型
    var a []int=make([]int,5,5)
    fmt.Println(a)  //[0 0 0 0 0]
    test(a)  //[999 0 0 0 0]
    fmt.Println(a)  //[999 0 0 0 0]

# test()
func test(a []int)  {
    a[0]=999
    fmt.Println(a)
}

//内存优化,copy函数
a:=[10000]int{1,2,3,4,5,}
b:=a[0:3]
fmt.Println(b)  //[1 2 3]
var c []int=make([]int,2,2)
copy(c,b)
fmt.Println(c)  //[1 2]

https://www.cnblogs.com/xiaoyuanqujing/p/11681169.html

猜你喜欢

转载自www.cnblogs.com/yangmeichong/p/11824441.html