zoukankan      html  css  js  c++  java
  • GoLang 环境部署

    环境部署

    Go编译器

    Downloads - Go

    ​ 安装位置:

    C:Program FilesGo

    image-20210502222044326

    其他配置

    • 创建一个任意的目录 GolangProjects,目录结构如下

      GolangProjects
      
      --bin
      
      --- crm.exe //主程序入口文件
      
      --pkg
      
      --- commlib.A //包文件
      
      --src
      

    配置环境变量

    • 添加环境变量 GOROOT : C:Program FilesGo Go 编译器的安装目录
    • 添加环境变量 GOBIN : E:CodeGoLangProjectsin 方便直接 Go
    • 添加环境变量 GOPATH: E:CodeGoLangProjects

    vs code 配置环境

    tools 怎么来的

    Clone 无需多言

    推荐使用:SourceTree ,主要界面看着挺爽

    怎么摆放

    在本地go_path 目录下新建文件夹,如下结构

    -- go path
    --- bin
    --- pkg
    --- src
    ---- github.com
    ------ Go-zh
    ------- tools //https://github.com/Go-zh/tools.git
    ---- golang.org
    ----- x
    ------ mod //https://github.com/golang/mod.git
    ------ sys //https://github.com/golang/sys.git
    ------ tools //https://github.com/golang/tools.git
    ------ xerrors //https://github.com/golang/xerrors.git
    

    安装命令

    打开 go-path 目录的下的src 目录,地址栏里输入 cmd ,启动终端,输入如下命令:
    
    1. go install golang.org/x/tools/cmd/guru
    2. go install golang.org/x/tools/cmd/gorename
    3. go install golang.org/x/tools/cmd/fiximports
    4. go install golang.org/x/tools/cmd/gopls 
    5. go install golang.org/x/tools/cmd/godex
    

    注意:

    我个人在第4点出错了,原因是因为英文官方的tools中按照位置找过去没有gopls;

    百度过后才下载的中文社区的,由此才看到前面的目录结构。

    所以到这要安装gopls,执行如下命令:

    go install github.com/Go-zh/tools/cmd/gopls
    

    vscode运行代码

    • 一般姿势:

      启动vscode终端,cd 到 go-path 目录下的src,再找到指定指定go文件,例如:go run app.go

    • 进阶姿势:

      启动vscode扩展,安装 code run 插件,安装按完重启编辑器,只需要右键选择code run 即可,或者快捷键 ctrl + alt + n

    运行代码

    src 目录下添加go文件

    -src

    --crm

    ---app.go

    -- app.go
    
    package  main
    
    import "fmt"
    
    func main()  {
    	fmt.Printf("Hello Go~ 叫爸爸~")
    }
    

    --commlib

    ---page

    package commlib
    
    func Add(i int ,j int)int {
    	return i+j
    }
    

    运行有三种方式:

    ​ 进入项目目录执行:

    • go run app.go
    • go build app.go 执行完此命令后,会在同级目录下面添加同名exeapp.exe可执行程序,然后cmd中执行exe程序即可。与第一种方式相同,只是go run 相当于一起把此方式中的两步骤一次执行完毕。
    • go install 执行完命令后,会在外面那个Bin 文件夹生产一个exe可执行文件,crm.exe,也可以在cmd命令中执行,于上面第二种方式的区别在于,会在Bin文件夹中生成exe可执行文件。但是如果生成的项目不是主程序入口、只有方法的话,就会生成包文件commlib.A文件,类似于C# 中类,存放在bin文件夹的同级目录pkg文件夹中。

    Go 包管理

    初识包管理

    • 一个文件夹也可以称之为一个包
    • 在文件夹(包)中可以创建多个文件
    • 在同一个包下的每个文件中必须指定包名称且相同

    包的分类

    • main包,如果是main包,必须写一个 main函数,以此作为程序的入口,又称为主函数,编译生成后会生成一个可执行文件。
    • main

    调用包

    调用包文件内的方法:

    package  main
    
    import (
    	"commlib" //这里会引入包
    	"fmt"
    	"strconv" //引入包
    )
    
    func main()  {
        //println 自带输出换行
    	fmt.Println("Hello Go~ ")
    	//调用
    	var num int = commlib.Add(1,6)
        //strconv.itba()方法,int 转 string
    	fmt.Println(strconv.Itoa(num))
    
    }
    
    package commlib
    
    func Add(i int ,j int)int {
    	return i+j
    }
    

    包定义规范

    • 定义包文件之后,包内的函数首字母必须得大写
    • 大写和小写的区别:
      • 大写:类似于C# 中的 public 修饰符,包的外部可以进行调用
      • 小写:类似于C# 中的 internal修饰符,仅限于包内部使用

    截图

    image-20210505225640086

    ​ 2021.05.05

    基础知识

    输出

    在终端输出前置语言例如:请输入账户名或者密码等等...

    • 内置函数
      • print
        • 默认打印两个print 是连在一起的,如果想要达到换行效果需要在内容尾部加上
      • println
        • 默认打印两个println 是自带换行效果的
    • fmt
      • fmt.print
        • 效果通内置函数 print 相仿
      • fmt.println
        • 同上,平时推荐使用此方法
      • fmt.println扩展:
        • fmt.println("我叫","Harris","年龄","18") 中间自带空格
        • 格式化显示:
          • fmt.printF()
    • 在以上两种方式的输出中推荐使用 fmt,原因:
      • Golang官方给出的回答是,在以后的规划中,不保证内置函数可以继续使用,为防止后面禁用内置函数后,代码出问题。

    注释

    • 单行注释 //
    • 多行注释 /* */
    • GoLand 快捷键 Ctrl+?

    变量

    • 概述

      • Go 是静态类型语⾔,不能在运⾏期改变变量类型
      • 使⽤关键字 var 定义变量,⾃动初始化为零值。如果提供初始化值,可省略变量类型,由 编译器⾃动推断。
      • 声明的变量必须使用 如果声明不使用,则报错 编译器会将未使⽤的局部变量当做错误
    • 变量的作用域

      • ​ 全局变量:没有写在函数内的变量,称之为全局变量,个人理解。

        var name string = "Harris"
        var name = "Harris"
        var {
            v1 = "a"
            v2 = "b"
            v3 = 18
            v4 int
        }
        name := "Harris" //这种不行滴
        
      • 局部变量:函数内的变量 局部就和C#差不多了

        func main(){
            var name string = "Harris"   
            name := "Harris"    
            var name = "Harris"    
            var{
                name = "Harris"
                age = 18
            }
        }
        
      • 多变量赋值时,先计算所有相关值,然后再从左到右依次赋值

        data, i := [3]int{0, 1, 2}, 0
        i, data[i] = 2, 100 // (i = 0) -> (i = 2), (data[0] = 100)
        fmt.Println(i,data)
        //结果:2 [100 1 2]
        
      • 特殊只写变量 "_",⽤于忽略值占位

        func test() (int, string) {
         	return 1, "abc"
        }
        
        func main() {
             _, s := test()
             fmt.Println(s)
            //结果:abc
        }
        
      • 编译器会将未使⽤的局部变量当做错误

        func main() {
         	i := 0 // Error: i declared and not used。(可使⽤ "_ = i" 规避)
        }
        

    常量

    • 常量值必须是编译期间固定的数字、字符串、布尔值

      const x,y int = 1,2     //多常量初始化
      
      const z = "Hello World" //类型推断
      
      const{
          a,b = 1,2
          c bool = true
      }
      
      func main(){
          const x = "xxxx" //这个时候如果没有使用上述已经定义好的常量,不会报错
      }
      
    • 常量可以使用在编译期间确定的函数

      const a,b int =1,2
      
      const c = "abc"
      
      const x = len(c)
      
      const y = unsafe.Sizeof(x) //这个方法是用来计算字节的,64为系统中,字符串和整形的字节一个都是8
      
      fmt.Println(a)
      
      fmt.Println(b)
      
      fmt.Println(c)
      
      fmt.Println(x)
      
      fmt.Println(y)
      
      //结果:
      /*
      1
      2
      abc
      3
      8*/
      

    枚举

    • 关键字 iota 定义常量组中从 0 开始按⾏计数的⾃增枚举值。

      const(
          Sunday = iota   //0
          Monday          //1,通常省略后面的表达式
          Tuesday			//2
          Wednesday		//3
          Thursday		//4
          Friday			//5
          Saturday		//6
      )
      const (
          _ = iota // iota = 0
          KB int64 = 1 << (10 * iota) // iota = 1  << 是左移运算符
          MB // 与 KB 表达式相同,但 iota = 2
          GB
          TB
      )
      
      fmt.Println(KB,MB,GB) //1024 1048576 1073741824
      
    • 在同⼀常量组中,可以提供多个 iota,它们各⾃增⻓。

      const (
          A, B = iota, iota << 10 // 0, 0 << 10
          C, D // 1, 1 << 10
      )
      
      fmt.Println(A,B,C,D) //0 0 1 1024
      
    • 如果 iota ⾃增被打断,须显式恢复

      const (
          A = iota // 0
          B // 1
          C = "c" // c
          D // c,与上⼀⾏相同。
          E = iota // 4,显式恢复。注意计数包含了 C、D 两⾏。
          F // 5
      )
      
      fmt.Println(A,B,C,D,E,F)//0 1 c c 4 5
      
    • 可通过⾃定义类型来实现枚举类型限制

      type Color int
      
      const (
           Black Color = iota
           Red
           Blue
      )
      
      func test(c Color)Color {
          return c
      }
      
      func main() {
           c := Black
           fmt.Println(test(c))     // 0
           x := 1
           test(x) // Error: cannot use x (type int) as type Color in function argument;写的时候就会报错没法转换
      }
      

    数据类型

    image-20210515232851239

    • 空指针值 nil,⽽⾮ C/C++ NULL。

    引用类型

    切片(Slice)

    实现类似动态数组的功能

    package commlib
    
    import "fmt"
    
    func SliceTest1()  {
    	x:=make([]int,0,5)//声明一个容量为5的切片
    
    	for i:=0;i<8;i++ {
    		x= append(x,i) //向切片内追加数据,当超出容量后,自动分配更大的容量空间
    	}
    
    	fmt.Println(x)
    }
    

    输出结果:

    image-20210514230715956

    channel 通道

    image-20210519220142304

    表达式

    常用

    package commlib
    
    import "fmt"
    
    //ExpressionTest
    func ExpressionTest()  {
    
    	//if
    	fmt.Println("******IF******")
        
    	x:=100
    	y:=6
    
    	if x > 0{
    		fmt.Println("x+")
    	}else if x < 0{
    		fmt.Println("x-")
    	}else {
    		fmt.Println("0")
    	}
    
    	// swich
    	fmt.Println("******swich******")
        
    	switch {
    		case x > 0:
    			fmt.Println("100")
    		case x<0:
    			fmt.Println("250")
    		default:
    			fmt.Println("俩250")
    	}
    
    	// for
    	fmt.Println("******for++******")
        
    	for i:=0;i<5;i++ {
    		fmt.Println(i)
    	}
        
    	fmt.Println("******for--******")
        
    	for i:=5;i>1;i--{
    		fmt.Println(i)
    	}
        
    	fmt.Println("******相当于while(x<10)******")
    	
        for y<10{
    
    		y++
    
    		fmt.Println(y)
    	}
    	
        fmt.Println("******相当于while(true)******")
    	
        for{
    		fmt.Println(x)
    
    		x = x-50
    
    		if x == 0 {
    			break
    		}
    	}
    	
        fmt.Println("******返回索引和值******")
    	
        arr:=[]int{1,2,3,4,5}
    
    	for i,n := range arr{
    		fmt.Println(i,":",n)
    	}
    }
    

    执行结果:

    image-20210514224453702

    标签

    for 标签

    fmt.Println("给For 打标签,应用 break | continue 跳出或者终止循环")
    
    f1:for i:=0;i<4;i++{ //f1 标签
        for j:=0;j<4;j++{
            if i==2{
                break f1  //此处结束的循环是f1 标签所对应的i for 循环
            }
            fmt.Println(i,j)
        }
    }
    

    输出结果:

    image-20210515165154495

    goto 跳跃

    • 跳跃到指定行,然后向下执行代码
    package api
    
    import "fmt"
    
    func GotoMethod()  {
    	fmt.Println("请输入姓名:")
    	var name string
    	fmt.Scanln(&name)
    
    	if name == "Harris"{
    		goto SVIP
    	}else if name=="Dongjie"{
    		goto VIP
    	}
    
    	fmt.Println("预约...")
    VIP:
    	fmt.Println("等号...")
    SVIP:
    	fmt.Println("治疗...")
    }
    

    image-20210517214916383image-20210517214945026image-20210517215011356

    字符串格式化

    package api
    
    import "fmt"
    
    func StringFormatMenthod()  {
    	var name,address,action string
    
    	fmt.Println("请输入姓名")
    
    	fmt.Scanln(&name)
    
    	fmt.Println("请输入地址")
    
    	fmt.Scanln(&address)
    
    	fmt.Println("请输入行为")
    
    	fmt.Scanln(&action)
    
    	result := fmt.Sprintf("我叫%s,我正在%s旁边%s",name,address,action)
    
    	fmt.Println(result)
    }
    

    输出:

    image-20210517220631093

    运算符

    位运算符

    进制转换:

    例如:101000 -> 2*5 + 2**3 -> 32 + 8 = 40

    1. 按位进行与运算(全为1,才得1)
    
    r1 := 5 & 99
    5  -> 0000101
    99 -> 1100011
          0000001 -> 1
    
    2. 按位进行或运算(只要有1,就得1)
    
    r2 := 5 | 99
    5  -> 0000101
    99 -> 1100011
          1100111 -> 2*6 +2*5 +2*2 + 2*1 + 2*0 -> 64+32+4+2+1 = 103
    
    3. 按位进行异或运算(上下不同,就得1)
    
    r3 := 5 ^ 99
    5  -> 0000101
    99 -> 1100011
          1100110 -> 2*6 +2*5 +2*2 + 2*1 -> 64+32+4+2 = 102
    
    4. 按钮进行左移运算
    
    r4 := 5 << 2
    5  -> 0000101 -> 101 //前面的0可以省略
    所以:101 左移之后 后面补0 -> 10100 -> 2*4+2*2 -> 16+4 = 20
    
    5. 按位进行右移运算
    
    r5 := 5 >> 1
    5  -> 0000101 -> 101 //前面的0可以省略
    所以:101 右移之后 10 右移1位,后面咬去1位, -> 10 -> 2*1 = 2
    

    image-20210517230842863

    补充:

    • 十进制转二进制

      十进制 二进制(逢二进一)
      0 0
      1 1
      2 10
      3 11
      4 100
      5 101
      6 110
      7 111
      8 1000
      9 1001
      10 1010

    函数

    package commlib
    
    import (
    	"errors"
    	"fmt"
    )
    
    // 函数可以定义多个返回值,甚至对其命名
    func FunctionTest(a, b int) (int, error) {
    	if b == 0 {
    		return 0, errors.New("FunctionTest")
    	}
    	return a / b, nil
    }
    
    func FunctionTest2() {
    	a, b := 1, 0 //定义多个变量
    
    	c, err := FunctionTest(a, b) //接受多个返回值
    
    	fmt.Println(c, err)
    }
    
    //函数是第一类型,可以作为参数或者返回值
    func FunctionTest3(x int)func()  {//返回函数类型
    	return func() {//匿名函数
    		fmt.Println("返回参数为函数",x)//闭包
    	}
    }
    
    func FunctionTest4()  {
    	x:=100
    
    	f:=FunctionTest3(x)//返回函数
    
    	f()//执行函数
    }
    
    //通过关键字 defer 来修饰动作标识最后执行
    func FunctionTest5(a,b int)  {
    
    	defer fmt.Println("延迟执行的动作")
    
    	fmt.Println("正在执行的动作")
    
    	fmt.Println(a+b)
    }
    
    func FunctionTest6()  {
    	x,y := 10,0
    
    	FunctionTest5(x,y)
    }
    

    执行:

    fmt.Println("执行:FunctionTest2")//函数可以定义多个返回值,甚至对其命名
    commlib.FunctionTest2()
    fmt.Println("执行:FunctionTest4")//函数是第一类型,可以作为参数或者返回值
    commlib.FunctionTest4()
    fmt.Println("执行:FunctionTest6")//通过关键字 defer 来修饰动作标识最后执行
    commlib.FunctionTest6()
    

    执行结果:

    image-20210514224544469

    常见问题

    1. go.mod file not found in current directory or any parent directory; see 'go help modules'

      问题是go环境的问题:执行go env -w GO111MODULE=auto

    2. 修改配置:运行种类和包位置 可以解决运行只局限在某个文件的问题

    直如弦,死道边;曲如钩,反封侯
  • 相关阅读:
    两个半成品的ORM
    Mayberry小镇的管理 | 三种截然不同的领导风格 3M
    敏捷的目的(方向)错了以后……
    Error:java: Compilation failed: internal java compiler error
    java: -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符)
    看mybatis日志模块时涉及的动态代理
    看的顺眼的却Destination Unreachable
    如何下载钉钉回放视频
    不想学习时看一看会有帮助的,“但行好事,莫问前程”
    守护线程
  • 原文地址:https://www.cnblogs.com/houlin/p/14858109.html
Copyright © 2011-2022 走看看