go语言基础循环语句、数组、切片


一、包管理

  就是模块的意思,package main 代表的就是main包

  1.自定义包(例如在路径下建立day2.1文件夹,里面包含s1.go,s2.go。然后在文件夹外面建立test.go文件夹)

-go语言的代码必须放在gopath的src路径下

-包导入是从gopath的src路径下开始检索(开始找)

-除了main包以外,建议包名就叫文件夹名,一个文件夹下的包名必须一致

-同一个包下,变量,函数只能定义一次

-同一个包下的变量和函数可以直接使用

-包内的函数或变量,想让外部包使用,必须首字母大写

-以后下的第三方包都是放在gopath的src路径下

    在day2.1里面的s1,s2(若包里面的变量要给外部使用,变量名需要首字母大写)

//day2.1里面的s1
package day2_1

import "fmt"


func Test()  {
    fmt.Println("我是day2下面的s1函数")
    fmt.Println(Name)
}



//day2.1里面的s2
package day2_1

import "fmt"

var Name = "aaa"

func test1()  {
    fmt.Println("我是day2下面的s2函数")
    fmt.Println(Name)
}

    在day2.1外面的test.go(此时调用day2.1里面的s1里面的函数Test)

package main

import (
    "fmt"
    "go/day2/day2.1"
)

func main()  {
    fmt.Println("我是根路径下的函数")
    day2_1.Test()
    fmt.Println(day2_1.Name)
}

  

  2、init函数(-不需要调用就会执行,例如下面只要执行函数就会触发,就会执行init函数。init函数可以定义多个

package day2_1

import "fmt"

//init特殊函数,初始化函数,在导包的时候就会执行,并且可以定义多个,可以用它来初始化包内的一些东西(比如下面初始化Name)
func init()  {
    Name = "bbb"
    fmt.Println("我是init函数")
}



func Test()  {
    fmt.Println("我是day2下面的s1函数")
    fmt.Println(Name)
}

 

  3、包的导入

方式一:直接导入
     -import "day02/mypackage"

方式二:-给包重命名(导入后就直接用名字.变量/函数在代码中使用) -import 名字 "day02/mypackage"
方式三:
-包只导入,不使用(例如执行某个包里面的init函数,而不执行其他函数,此时导入就会执行init函数,而其他函数不执行) -import _ "day02/mypackage"

 

  4、采用go mod 模式

-两种创建方式
1.
-命令行下输入:go mod init 项目名(也可以自己在任何路径下创建一个文件夹名),输入命令后在当前路径下创建出go.mod(该项目依赖go的版本,第三方包版本)
-项目路径的cmd窗口,go get 第三方包,就会在go.mod中加入依赖
-以后把项目copy给别人,别人执行:go get
-自己写的包,就放在自己项目路径下
-加代理的方式:手动写,goland中配置

2.
-在goland中创建项目时,直接指定modules,可以配置环境变量(加代理)

 

  5、if-else语句

package main

import "fmt"

//一定不要回车换行
func main()  {
    a := test()
    if a > 10{
        fmt.Println("a大于10")
    }else if a == 10{
        fmt.Println("a等于10")
    }else {
        fmt.Println("a小于10")
    }
}

func test() int {
    return 100
}

 

  6、循环

    没有while循环,没有do while循环,只有一个for循环

package main

/*
for循环
语法:
for 变量初始化条件;条件;变量自增/自减{
    循环内容
}
 */
func main()  {
    //基本使用
    //for i:=0;i<10;i++{
    //    fmt.Println(i)
    //}

    //省略初始化变量条件,放置到循环外
    //i:=0             //作用域范围大,不止在for内部,外部也可以用
    //for ;i<10;i++{
    //    fmt.Println(i)
    //}

    //省略第三部分,放置到循环外
    //i:=0           //作用域范围大,不止在for内部,外部也可以用
    //for ;i<10;{
    //    fmt.Println(i)
    //    i++
    //}

    //省略一和三部分的简略写法(这就是while循环)  for 条件{ 循环体内容}
    //i:=0
    //for i<10{
    //    fmt.Println(i)
    //    i++
    //}

    //死循环
    //for {
    //    fmt.Println("ssssss")
    //}

    //只是演示开多协程
    //for i:=0;i<4000;i++{
    //    go test2()
    //}

    //break :结束本次for循环,continue结束本次循环继续下一次循环
}
//func test2()  {
//    for  {
//        fmt.Println("sssss")
//    }
//
//}

 

  7、Switch

    switch 是一个条件语句,用于将表达式的值与可能匹配的选项列表进行比较,并根据匹配情况执行相应的代码块。它可以被认为是替代多个 if else 子句的常用方式

package main
func main() {
    //1 基本使用
    //num:=4
    //switch num {
    //case 1:
    //    fmt.Println("1")
    //case 2:
    //    fmt.Println("2")
    //case 3:
    //    fmt.Println("3")
    //case 4:
    //    fmt.Println("4")
    //}

    //2 默认情况
    //num:=40
    //switch num {
    //case 1:
    //    fmt.Println("1")
    //case 2:
    //    fmt.Println("2")
    //case 3:
    //    fmt.Println("3")
    //case 4:
    //    fmt.Println("4")
    //default:
    //    fmt.Println("我没有匹配")
    //}

    //3 多表达式判断
    //num:=40
    //switch num {
    //case 1,2,3,4,5,6,7,8:
    //    fmt.Println("1")
    //case 10,11,16:
    //    fmt.Println("2")
    //case 30:
    //    fmt.Println("3")
    //case 40,44,45:
    //    fmt.Println("4")
    //default:
    //    fmt.Println("我没有匹配")
    //}

    //4 无表达式的 switch
    //num:=80
    //switch  {
    //case num==12,num==13:
    //    fmt.Println("12,13")
    //case num==40,num==41:
    //    fmt.Println("40,41")
    //default:
    //    fmt.Println("我没有匹配")
    //}
    
    //5 Fallthrough(此时相当于全部执行下面代码。即全部打印)
    //num:=12
    //switch  {
    //case num==12,num==13:
    //    fmt.Println("12,13")
    //    fallthrough
    //case num==40,num==41:
    //    fmt.Println("40,41")
    //    //fallthrough                       //穿透,只要看到fallthrough,无条件执行下一个case或者default
    //default:
    //    fmt.Println("我没有匹配")
    //}
}

  

  8、数组(基础数组、数值长度、循环数组、多维数组相关)

    数组是同一类型元素的集合。可以放多个值,但是类型一致,内存中连续存储。Go 语言中不允许混合不同类型的元素

package main

import (
    "fmt"
)

func main() {

    //1 数组的定义,数组的大小,在定义阶段就确定了,而且不能改
    //定义了一个大小为3的string类型数组,里面可以放3个字符串
    //var names [3]string
    //var ages [3]int8
    //fmt.Println(ages)

    //2 数组赋值
    //var ages [3]int8
    //ages[0]=99           给第一个索引位设置为99
    //ages[2]=88
    //fmt.Println(ages)
    //fmt.Println(ages[1])

    //3 定义并初始化,
    //var ages [3]int=[3]int{1,2,3}
    //var ages [3]int=[3]int{1,2}
    //var ages [3]int=[3]int{}
    //var ages=[3]int{}
    //ages:=[3]int{1,3,4,7}  //不允许多放,此时报错
    //fmt.Println(ages)

    //4 数组定义并初始化的其他。数组只要定义,长度就固定了,...后面放几个值,数组大小就是多少
    //var ages [9]int=[...]int{1,2,3,4,5,6,7,8}   //不支持这个
    //var ages =[...]int{1,2,3,4,5,6,7,8}
    //ages :=[...]int{1,2,3,4,8}
    //fmt.Println(len(ages))

    //5 数组的大小是类型的一部分
    //var a [2]int=[2]int{1,2}
    //var b [3]int=[2]int{1,3}
    //var b1 [2]int=[2]int{1,3}
    //b=a   //此时a,b为两个类型如果不是同一种类型,不允许相互赋值,而a,b1可以赋值
    //fmt.Println(b)

    //6 数组是值类型
    //var a [2]int=[2]int{1,2}
    //fmt.Println(a)       //[1 2]
    //test5(a)  //因为数组是值类型,go函数传参,都是copy传递,如果是值类型,函数内改了,不会影响原来的   [99 2]
    //fmt.Println(a)     [1 2]

    //7 数组长度  len()  数组长度在定义阶段已经固定
    //var a [2]int=[2]int{1,2}
    //fmt.Println(len(a))

    //8 数组循环
    //var a =[...]int{7,4,3,5,6,7}
    //fmt.Println(a[99])    会报错
    //fmt.Println(len(a))
    //普通循环
    //for i:=0;i<len(a);i++{
    //    fmt.Println(a[i])
    //}

    //通过range来循环  (range不是内置函数,是一个关键字,for,if,else),打印出索引
    //for i:=range a{
    //    fmt.Println(i)
    //}

    //如果用一个变量来接收,这个值是可迭代的索引
    //如果用两个变量来接收,这两个变量,一个是索引,一个具体的值
    //for i,value:=range a{
    //    fmt.Println(i)
    //    fmt.Println(value)
    //}

    //把数组循环打印出来,此时就是不要索引
    //for _,value:=range a{
    //    fmt.Println(value)
    //}

    // 9 多维数组
    //var a [3][3]int  //定义:表示数组里面再放数组  [[0 0 0] [0 0 0] [0 0 0]]
    //a[0][1]=99      //使用   [[0 99 0] [0 0 0] [0 0 0]]
    //fmt.Println(a)

    //定义并赋初值
    //var a [3][3]int=[3][3]int{{1},{1,2,3},{4,4,4}}           //[[1 0 0] [1 2 3] [4 4 4]]
    //var s =[3][3]string{{"aaa","xxx","yyy"},{},{}}        //[[aaa xxx yyy] [  ] [  ]]
    //fmt.Println(s)
    //fmt.Println(a)
    
    //循环多维数组
    //for _,value:=range s{
    //    for _,in_value:=range value{
    //        fmt.Println(in_value)
    //    }
    //}

    //10 数组定义并指定位置初始化
    //var names [100]int=[100]int{10:99,99:99}     //代表给第十个位置赋值99,且第99个位置也赋值99
    //var names [100]int=[100]int{10,11,2,44,99:99,45:88}   //表示0,1,2,3索引位置为10,11,2,44.索引99位置赋值99,索引45位置赋值88
    //fmt.Println(names)
    
}

func test5(a [2]int)  {
    a[0]=99
    fmt.Println(a)

}

 

  9、切片基础

    本质:切片是由数组建立的一种方便、灵活且功能强大的包装(Wrapper)。切片本身不拥有任何数据。它们只是对现有数组的引用

package main

func main() {
    //1 切片定义的第一种方式
    //定义一个数组
    //var a =[10]int{9,8,7,6,5,4,3,2,1,0}
    //基于数组,做一个切片
    //[]int 中括号中不带东西,就是切片类型
    //var b []int    此时也是定义切片
    //b:=a[:]
    //fmt.Println(b)                     //[9 8 7 6 5 4 3 2 1 0]
    //fmt.Printf("%T",b)         //[]int    []里面没有东西代表为切片类型
    //fmt.Println()
    //fmt.Printf("%T",a)         //[10]int     数组类型
    //fmt.Println()

    ////2 使用切片,取索引位值
    //fmt.Println(b[0])
    //fmt.Println(b[1])

    ////3 修改切片,会影响数组
    //b[0]=999
    //fmt.Println(b)
    ////数组会被修改
    //fmt.Println(a)

    ////4 修改数组,也会影响切片。
    //a[3]=333
    //fmt.Println(a)  //数组
    //fmt.Println(b) //切片

    // 5 切片只切数组一部分
    //var a =[10]int{9,8,7,6,5,4,3,2,1,0}
    //var b []int=a[3:5]       //此时[6 5]
    //fmt.Println(b)
    ////修改切片
    //b[0]=999
    //fmt.Println(b)
    //fmt.Println(a)         //虽然是改的b,但是也会影响a,此时a也会影响和b变化一样。 数组切片互相影响
    //a[4]=888
    //fmt.Println(b)
    //fmt.Println(a)

    //6 当多个切片共用相同的底层数组时,每个切片所做的更改将反映在数组中。abc都会相互影响
    //var a =[10]int{9,8,7,6,5,4,3,2,1,0}
    //var b []int=a[3:5]
    //var c []int=a[4:6]
    //fmt.Println(a)
    //fmt.Println(b)
    //fmt.Println(c)
    //b[1]=555
    //fmt.Println(a)
    //fmt.Println(b)
    //fmt.Println(c)

    ////7 切片的长度和容量
    //var a =[10]int{9,8,7,6,5,4,3,2,1,0}
    ////var b []int=a[3:4]
    //fmt.Println(a)
    //fmt.Println(b)
    //// 切片长度
    //fmt.Println(len(b))        此时切多少长度就是多少,此时为1
    //// 切片容量(我最多能存多少值)
    //fmt.Println(cap(b))     此时b的容量为7,因为是从3开始且,此时指针在索引位置3,对应a中的数值6,指针后面还有7位。所以容量为切片初始位置到原数组结束位置

    ////8 切片追加值
    //b=append(b,5)          [6,5]  会在索引3对应的值6后面加5
    //b=append(b,999)      
    ////到了临界点可再追加,但是临界点后的数据不能加进原数组,临界点前的数据可以影响原数组。
    //b=append(b,888)
    //fmt.Println(b)
    //fmt.Println(a)
    //
    //fmt.Println(len(b))// 长度是4
    //fmt.Println(cap(b))  //容量是6
    //b[0]=111
    //fmt.Println(b)
    //fmt.Println(a)

    //注意只要超出临界点追加,此时b就会新建一个数组,自动扩容,且容量为原来的两倍,此时对b修改,那么不会影响a数组

}

     切片之append()和copy()函数

      如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。

package main

import "fmt"

func main() {
    var numbers []int                //定义空切片
    printSlice(numbers)             //len=0 cap=0 slice=[]

    //允许追加空切片
    numbers = append(numbers, 0)
    fmt.Println(numbers)                 //[0]
    printSlice(numbers)                 //len=1 cap=1 slice=[0] 追加空切片后

    //向切片添加一个元素
    numbers = append(numbers, 1)
    fmt.Println(numbers)               //[0 1]
    printSlice(numbers)                //len=2 cap=2 slice=[0 1]

    // 同时添加多个元素
    numbers = append(numbers, 2,3,4)
    fmt.Println(numbers)               //[0 1 2 3 4]
    printSlice(numbers)                //len=5 cap=6 slice=[0 1 2 3 4]

    //创建切片 numbers1 是之前切片的两倍容量,创建切片用make
    numbers1 := make([]int, len(numbers), (cap(numbers))*2)
    fmt.Println(numbers1)             //[0 0 0 0 0] 
    printSlice(numbers1)             //len=5 cap=12 slice=[0 0 0 0 0]

    //拷贝 numbers 的内容到 numbers1 
    copy(numbers1,numbers)
    printSlice(numbers1)           //len=5 cap=12 slice=[0 1 2 3 4]
}

     

    切片之删除元素

      Go语言并没有对删除切片元素提供专用的语法或者接口,需要使用切片本身的特性来删除元素,根据要删除元素的位置有三种情况,分别是从开头位置删除、从中间位置删除和从尾部删除,其中                           删 除切片尾部的元素速度最快。

    1.从开头位置开始删除(直接移动数据指针)

a = []int{1, 2, 3}
a = a[1:] // 删除开头1个元素
a = a[N:] // 删除开头N个元素

      (不移动指针,不会导致内存空间结构的变化)

a = []int{1, 2, 3}
a = append(a[:0], a[1:]...) // 删除开头1个元素
a = append(a[:0], a[N:]...) // 删除开头N个元素

      (使用copy函数)

a = []int{1, 2, 3}
a = a[:copy(a, a[1:])] // 删除开头1个元素
a = a[:copy(a, a[N:])] // 删除开头N个元素

 

    2.从中间位置删除

a = []int{1, 2, 3, ...}
a = append(a[:i], a[i+1:]...) // 删除中间1个元素
a = append(a[:i], a[i+N:]...) // 删除中间N个元素
a = a[:i+copy(a[i:], a[i+1:])] // 删除中间1个元素
a = a[:i+copy(a[i:], a[i+N:])] // 删除中间N个元素

    

    3、从尾部删除

a = []int{1, 2, 3}
a = a[:len(a)-1] // 删除尾部1个元素
a = a[:len(a)-N] // 删除尾部N个元素

  例子:

package main
import "fmt"
func main() {
    seq := []string{"a", "b", "c", "d", "e"}
    // 指定删除位置
    index := 2

    // 查看删除位置之前的元素和之后的元素,index为索引位置
    fmt.Println(seq[:index], seq[index+1:]) //[a b] [d e]

    // 将删除点前后的元素连接起来
    seq = append(seq[:index], seq[index+1:]...) 
    fmt.Println(seq)      //[a b d e]
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM