mac安装Golang开发环境及快速入门

目录

一、Mac brew 安装go环境

1.1 安装步骤

1.2 设置GOPATH 及环境变量

1.3 编写第一个go程序

二、快速入门

2.1 快速入门需求

2.2 go学习(自用)

2.2.1 go基础程序

2.2.2 变量声明

2.2.3 常量和枚举

2.2.4 函数与多种返回值

2.2.5 init函数与import导包

2.2.6 import匿名、别名导包

2.2.7 defer调用顺序

2.2.8 数组的表示和动态数组 slice

2.2.9 map的声明使用

三、debug

3.1 go: cannot run *_test.go files

3.2 深拷贝(copy)和浅拷贝(slice切片)

3.3 引用传递


一、Mac brew 安装go环境

1.1 安装步骤

1)终端输入,也可以指定下载go版本

brew install go

2)查看golang当前版本

go version

3)查看当前golang环境 执行

go env

1.2 设置GOPATH 及环境变量

1)GOPATH 是工作目录,工作空间目录 go_project 就是一个目录,其中包含三个子目录:

  • src 目录包含Go的源文件,它们被组织成包(每个目录都对应一个包),
  • pkg 目录包含包对象,
  • bin 目录包含可执行命令。

如下图:

​2) 终端输入 vim .zshrc 添加:

GOPATH 后面加你自己的工作空间,这里是我自己建立的go_project

export GOPATH="/Users/mima6ge0/Documents/yanhan_practice/go_project"export PATH = $PATH:$GOPATH/bin

执行 source ~/.zshrc 生效,使用go env查看是否修改成功

1.3 编写第一个go程序

1)新建hellow.go文件

package mainimport "fmt"func main() {fmt.Println("hello, world")
}

2)进入文件所在目录,执行go run hellow.go,成功,如下图

二、快速入门

2.1 快速入门需求

  • 具备1种后端编程语言开发经验(C/C++/Java/Python/PHP)
  • 具备基本的网络编程能力和并发思想
  • 了解计算机基本体系结构
  • 了解Linux基础知识

2.2 go学习(自用)

2.2.1 go基础程序

package main //程序的包名
// main函数
//多个文件导入
import ("fmt""time"
)func main() { //函数的"{"必须和函数名在一行,换到下一行就是语法错误,强制代码风格fmt.Println("hellow Go!")//go语言不需要";",可有可无time.Sleep(10 * time.Second)
}

2.2.2 变量声明

package main
/*
变量的声明方法*/
import "fmt"
//全局变量,冒等方法不支持全局,其他的都可以
var A int = 100
func main() {//声明变量默认值是0var a intfmt.Println("a = ", a)fmt.Printf("type of a = %T\n", a)//声明变量,初始化var b int = 100fmt.Println("b = ", b)fmt.Printf("type of v = %T\n", b)//初始化可以省去变量类型,通过值去匹配变量的树枝类型var c = 100fmt.Println("c = ", c)fmt.Printf("type of c = %T\n", c)//字符串var d string = "dasda"fmt.Println("d = ", d)fmt.Printf("type of d = %T\n", d)//最常用方法:冒等,省略var,直接自动匹配,":="初始化加赋值,函数内部使用e := 3213.432fmt.Println("e = ", e)fmt.Printf("type of e = %T\n", e)fmt.Println("A = ", A)fmt.Printf("type of A = %T\n", A)//声明多个变量var x, y int = 100, 100fmt.Println("x = ", x, ", y = ", y)var m, n = 100, "88090"n = "kjuhku"fmt.Println("m = ", m, ", n = ", n)//多行多变量声明var (xx int = 121zz bool = true)fmt.Println("xx = ", xx, ", zz = ", zz)
}

2.2.3 常量和枚举

package mainimport "fmt"//const 可以定义枚举类型
const (//可以在const里面添加一个关键字 iota,每行的iota都会累加1,第一行的iota的默认值是0BEIJING = 10 * iota // iota = 0SHANGHAI		//iota = 10SHENZHEN		//iota = 20
)const (a, b = iota + 1, iota + 2 //iota = 0, a = 1, b = 2c, d					  //iota = 1, c = 2, d = 3e, f					  //iota = 2, e = 3, f = 4g, h = iota * 2, iota * 3 //iota = 3, g = 6, h = 9i, k					  //iota = 4, i = 8, k = 12
)func main() {//常量,只读,不允许修改const a int = 100fmt.Println("a = ", a)fmt.Println("BEIJING = ", BEIJING)fmt.Println("SHANGHAI = ", SHANGHAI)fmt.Println("SHENZHEN = ", SHENZHEN)fmt.Println("a = ", a, "b = ", b)fmt.Println("c = ", c, "d = ", d)fmt.Println("e = ", e, "f = ", f)fmt.Println("g = ", g, "h = ", h)fmt.Println("i = ", i, "k = ", k)//iota只能在const里面使用,var里面不可以}

2.2.4 函数与多种返回值

package mainimport "fmt"//返回一个值,匿名
func foo1(a string, b int) int {fmt.Println("a = ", a)fmt.Println("b = ", b)c := 100return c
}//返回多个值,匿名
func foo2(a string, b int) (int, int) {fmt.Println("--------foo2----------")fmt.Println("a = ", a)fmt.Println("b = ", b)return 888, 9999
}//返回多个返回值,有形参名称
func foo3(a string, b int) (r1 int, r2 int) {fmt.Println("--------foo3----------")fmt.Println("a = ", a)fmt.Println("b = ", b)r1 = 1000r2 = 100000return 
}func foo4(a string, b int) (r1, r2 int) {fmt.Println("--------foo4----------")fmt.Println("a = ", a)fmt.Println("b = ", b)//r1, r2属于foo3的形参,初始化默认的值是0,作用域空间是整个foo4函数{}的整体fmt.Println("未赋值:r1 = ", r1)fmt.Println("未赋值:r2 = ", r2)r1 = 1000r2 = 100000return 
}func main() {c := foo1("func1", 1)fmt.Println("c = ", c)ret1, ret2 := foo2("func2", 2)fmt.Println("ret1 = ", ret1)fmt.Println("ret2 = ", ret2)r1, r2 := foo3("func3", 3)fmt.Println("r1 = ", r1)fmt.Println("r2 = ", r2)r1, r2 = foo4("func4", 4)fmt.Println("r1 = ", r1)fmt.Println("r2 = ", r2)}

2.2.5 init函数与import导包

文件目录树状图

lib1.go 代码:

package lib1import "fmt"//当前lib1包提供的API
//首字母大写的话代表当前接口对外开放,首字母小写只能在该文件下使用
func Lib1Test () {fmt.Println("Lib1Test() ...")
}func init () {fmt.Println("lib1 init ...")
}

lib2.go 代码: 

package lib2import "fmt"//当前lib2包提供的API
func Lib2Test () {fmt.Println("Lib2Test() ...")
}func init () {fmt.Println("lib2 init ...")
}

main.go代码:

package main//需要在GOPATH下
import ("GolangStudy/5_init/lib1""GolangStudy/5_init/lib2"
)func main () {lib1.Lib1Test()lib2.Lib2Test()
}

2.2.6 import匿名、别名导包

基于2.2.5的代码

package main//需要在GOPATH下,go语言语法比较严格,导入必须使用
import (// _ 匿名导包,导入但是不使用,不会报错_ "GolangStudy/5_init/lib1"//mylib2是lib2的别名//mylib2 "GolangStudy/5_init/lib2"//可以不写包名直接使用Lib2Test(),把方法导入当前main包里面,不建议使用,如果有重名函数,会出现问题. "GolangStudy/5_init/lib2"
)func main () {//lib1.Lib1Test()//mylib2.Lib2Test()Lib2Test() 
}

总结:

2.2.7 defer调用顺序

package main
/*
defer的执行顺序是在函数体全部执行完以后和结束之前,
多个defer语句是压栈的,defer在return后面执行
*/
import "fmt"func func1() {fmt.Println("A")
}func func2() {fmt.Println("B")
}func func3() {fmt.Println("C")
}func main () {defer func1()defer func2()defer func3()
}

2.2.8 数组的表示和动态数组 slice

1)固定长度数组表示,遍历等(不建议,不常用)

package main
import "fmt"//不建议使用,可以使用动态数组
func printArray (array [4]int){//值拷贝fmt.Println("---------------输出函数--------------")for i := 0; i < len(array); i++ {fmt.Println("array2_value = ", array[i])}//如果要对数组的值进行修改,下面这种传参是改不了的// array[0] = 10000
}
func main () {// 固定长度数组var array1 [10]intfor i := 0; i < len(array1); i++ {fmt.Println("array1_value = ", array1[i])}array2 := [10]int{1, 2, 4, 5}array3 := [4]int{1, 2, 4, 5}for index, value := range array2 {fmt.Println("array2_index = ", index, "array2_value = ", value)}printArray(array3)// 打印数组类型fmt.Printf("array1 type : %T\n", array1)fmt.Printf("array2 type : %T\n", array2)fmt.Printf("array3 type : %T\n", array3)}

2)动态数组,切片,slice

package main
import "fmt"func printArray(array []int) {// 引用拷贝,传递的是数组指针,所以array[0]会被修改为100array[0] = 100// _ 表示匿名的变量,不被使用也不会发生问题for _, value := range array {fmt.Println("value = ", value)}
}
func main() {// 动态数组,切片,slicearray := []int{1, 2, 3, 4}//查看array的类型fmt.Printf("array type : %T\n", array)printArray(array)}

3)slice四种定义声明方式

package mainimport ("fmt")
func main() {// 声明slice1是一个切片,并且初始化,长度是3,默认值是1, 2, 3// slice1 := []int{1, 2, 3}// 声明slice1是一个切片,但是没有分配空间,len = 0,value = []// var slice1 []int // 可以通过make来开辟几个空间,这时候len = 3,value = [0, 0, 0]// slice1 = make([]int, 3)// 声明slice1是一个切片,通过make来开辟3空间,这时候len = 3,value = [0, 0, 0]// var slice1 []int = make([]int, 3)// 声明slice1是一个切片,通过make来开辟3空间,这时候len = 3,value = [0, 0, 0],通过:=推测出他是一个切片slice1 := make([] int, 3)fmt.Printf("len = %d , value = %v\n", len(slice1), slice1)// 判断一个切片是否为空if slice1 == nil {fmt.Println("slice1 is null!")} else {fmt.Println("slice2 is not null!!")}
}

4)slice切片追加与截取

package mainimport "fmt"
func main () {// 切片中len和cap是不同的var numbers = make([] int, 3, 5) // len = 3, cap容量 = 5fmt.Printf("len = %d, cap = %d, value = %v\n", len(numbers), cap(numbers), numbers)//追加一个元素7numbers = append(numbers, 7)fmt.Printf("len = %d, cap = %d, value = %v\n", len(numbers), cap(numbers), numbers)numbers = append(numbers, 8)// 当追加元素时,容量已满,则自动扩充为原来一开始定义的cap的二倍,扩充为10numbers = append(numbers, 9)fmt.Printf("len = %d, cap = %d, value = %v\n", len(numbers), cap(numbers), numbers)// 没有定义容量的情况,但是在容量已满的情况下追加元素,直接扩充为len的二倍var numbers2 = make([] int, 3)fmt.Printf("len = %d, cap = %d, value = %v\n", len(numbers2), cap(numbers2), numbers2)numbers2 = append(numbers2, 4)fmt.Printf("len = %d, cap = %d, value = %v\n", len(numbers2), cap(numbers2), numbers2)// slice切片s := [] int{1, 2, 3, 4}s1 := s[0:2] //s1是s中的索引在[0, 2)区间的元素,和python类似fmt.Println("s1 = ", s1)s2 := s[1:] //s1是s中的索引在[1, len(s))区间的元素,和python类似fmt.Println("s2 = ", s2)//如若修改s1里面的元素,s也会随之改变,因为这种切片相当于指针指向了s,所以改s1值,s和s1会一起发生改变(浅拷贝)s1[0] = 20000fmt.Println("s = ", s)// go提供了copy函数,切片的时候只将值复制过来,(深拷贝)s3 := make([] int, 3) //[0, 0, 0]// 将s2的值依次拷贝到s3中copy(s3, s2)fmt.Println("s3 = ", s3)
}

2.2.9 map的声明使用

1)map的声明

package mainimport "fmt"
func main() {// 第一种声明方式var map1 map[string]stringif map1 == nil {fmt.Println("map1是一个空map!!")}// 使用前,需要通过make来给map分配数据空间map1 = make(map[string]string, 3)map1["one"] = "java"map1["two"] = "php"map1["three"] = "python"fmt.Println("map1 = ", map1)// 第二种声明方式,直接:=map2 := make(map[int]string)map2[1] = "baidu"map2[2] = "tengxun"map2[3] = "ali"fmt.Println("map2 = ", map2)// 第三种声明方式,一般带有初始化的map用这种方式map3 := map[string]string{"王八": "绿豆","傻子": "小丑",}fmt.Println("map3 = ", map3)
}

2)map的使用

package mainimport ("fmt"
)func printMap (city_map map[string]string) {// 遍历for key, value := range city_map {fmt.Println("key = ", key, ", value = ", value)}
}func changeMap (city_map map[string]string) {// city_map是一个引用传递,传递过来是地址,可以修改city_mapcity_map["UK"] = "london"
}
func main() {cityMap := make(map[string]string)cityMap["china"] = "beijing"cityMap["USA"] = "DC"printMap(cityMap)// 删除delete(cityMap, "china")fmt.Println("-----------删除后---------------")printMap(cityMap)// 修改cityMap["USA"] = "london"fmt.Println("-----------修改后---------------")printMap(cityMap)// 增加cityMap["china"] = "beijing"fmt.Println("-----------增加后---------------")printMap(cityMap)changeMap(cityMap)fmt.Println("-----------函数增加后---------------")printMap(cityMap)}

2.2.10 面向对象

1)结构体的使用

package mainimport "fmt"// 声明一种数据类型,myint是int的别名
type myint int
// 声明结构体
type Book struct{title stringauth string
}func changeBook (book Book) {// 传递了一个book的副本book.title = "三体"
}func changeBook2 (book *Book) {// 指针传递book.title = "生死疲劳"
}func main () {var a myint = 232fmt.Println("a = ", a)fmt.Printf("type of a is %T\n", a)var book1 Bookbook1.title = "活着"book1.auth = "余华"fmt.Printf("%v\n", book1)changeBook(book1)// 使用上面changeBook,修改值并没有成功fmt.Printf("%v\n", book1)// 参数是地址,所以要加"&"changeBook2(&book1)fmt.Printf("%v\n", book1)}

2)面向对象类的表示

三、debug

3.1 go: cannot run *_test.go files

背景:将go文件命名成array_test.go报错go: cannot run *_test.go files

原因:_test.go 是golang专用的测试文件

解决:改名

3.2 深拷贝(copy)和浅拷贝(slice切片)

https://blog.csdn.net/weixin_45440484/article/details/131740125

3.3 引用传递

引用传递是一种变量传递的方式,它不是直接传递变量的值,而是传递变量的内存地址(引用)。在引用传递中,被调用函数可以通过引用修改原始变量的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

18.Lucas-Kanade光流及OpenCV中的calcOpticalFlowPyrLK

文章目录 光流法介绍OpenCV中calcOpticalFlowPyrLK函数补充reference 欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; 光流法介绍 光流描述了像素在图像中的运动&#xff0c;就像彗星☄划过天空中流动图像。同一个像素&#xff0c;随着时…

手写对象浅比较(React中pureComponent和Component区别)

PureComponent和Component的区别 PureComponent会给类组件默认加一个shouldComponentUpdate这样的周期函数 //PureComponent类似自动加了这段shouldComponentUpdate(nextProps,nextState){let { props, state } this;// props/state:修改之前的属性状态// nextProps/nextState…

047、TiDB特性_TopSQL

TopSQL 之前 之前没有办法找单个TiKV Server的语句。只能查找整个集群的慢语句。 TopSQL之后 指定TiDB及TiKV实例正在执行的SQL语句CPU开销最多的Top 5 SQL每秒请求数、平均延迟等信息 TopSQL 使用 选择需要观察负载的具体TiDB Server或TiKV实例 观察Top 5 类SQL 查看某…

用IDEA写第一个Spring程序 HelloWorld

用IDEA写第一个Spring程序 HelloWorld 环境 Orcal JDK&#xff1a;1.8.0_341 maven&#xff1a;3.9.3 Spring&#xff1a;5.3.10 IDEA&#xff1a;2023.1.2 1. 安装JDK和IDEA 2. 安装maven并配置环境变量、换源 3. IDEA中maven属性配置&#xff0c;主要是版本和settings文件及…

python+selenium进行cnblog的自动化登录测试

Web登录测试是很常见的测试&#xff0c;手动测试大家再熟悉不过了&#xff0c;那如何进行自动化登录测试呢&#xff01;本文就基于pythonselenium结合unittest单元测试框架来进行一次简单但比较完整的cnblog自动化登录测试&#xff0c;可提供点参考&#xff01;下面就包括测试代…

centos7 docker 安装sql server 2019

contos7安装sql server docker最低1.8或更高 卸载旧的docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 装docker依赖包 #安装所需资源包 sudo yum install -…

uniapp实现微信小程序自带的分享功能

定义 share.js 文件 export default {data() {return {// 默认的全局分享内容share: {title: 标题,path: /pages/index/index, // 全局分享的路径imageUrl: , // 全局分享的图片(可本地可网络)}}},// 定义全局分享// 1.发送给朋友onShareAppMessage(res) {return {title: this…

数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列)

目录 引例 希尔增量序列 原始希尔排序 代码&#xff08;C语言&#xff09; 时间复杂度 更多增量序列 Hibbard增量序列 Sedgewick增量序列 希尔排序&#xff08;by Donald Shell&#xff09; 引例 给以下序列进行排序&#xff1a; 先以5的间隔进行插入排序&#xff1a…

设计模式之桥接模式

写在前面 本文看下桥接设计模式。 1&#xff1a;介绍 1.1&#xff1a;什么时候桥接设计模式 当一个业务场景由多个变化维度组成&#xff0c;并且这多个变化的维度到底有多少种情况是不确定&#xff0c;比如现在我们要为瑞幸咖啡写一个系统&#xff0c;很自然的&#xff0c;…

2023.7.16 第五十九次周报

目录 前言 文献阅读:跨多个时空尺度进行预测的时空 LSTM 模型 背景 本文思路 本文解决的问题 方法论 SPATIAL 自动机器学习模型 数据处理 模型性能 代码 用Python编写的LSTM多变量预测模型 总结 前言 This week, I studied an article that uses LSTM to solve p…

Element分页组件自定义样式

样式效果 页面代码 <el-paginationsize-change"handleSizeChange"current-change"handleCurrentChange":current-page"page.page":page-sizes"[10, 20, 30, 40]":page-size"page.size"layout"total, sizes, prev, …

如何用https协议支持小程序

步骤一&#xff1a;下载SSL证书 登录数字证书管理服务控制台。在左侧导航栏&#xff0c;单击SSL 证书。在SSL证书页面&#xff0c;定位到目标证书&#xff0c;在操作列&#xff0c;单击下载。 在服务器类型为Nginx的操作列&#xff0c;单击下载。 解压缩已下载的SSL证书压缩…

使用 jmeter 进行审批类接口并发测试

目录 前言&#xff1a; 背景&#xff1a; 难点&#xff1a; 场景 a&#xff1a; 场景 b&#xff1a; 前言&#xff1a; 使用JMeter进行审批类接口的并发测试是一种有效的方法&#xff0c;可以模拟多个用户同时对接口进行审批操作&#xff0c;以评估系统在高负载情况下的性…

Java+Vue+Uniapp全端WMS仓库管理系统

详情图片为运行截图,功能列表: 1、数据管理:物料数据管理、物料Bom管理、物料组管理、物料分类管理、供应商管理、仓库管理、货位管理、车间管理 2、采购管理:物料标签管理、入库单管理、入库退货管理 3、质检管理:质检单管理(包括单据号、单据类型、创建时间、检验状态…

4. CSS用户界面样式

4.1什么是界面样式 所谓的界面样式,就是更改一些用户操作样式,以便提高更好的用户体验。 ●更改用户的鼠标样式 ●表单轮廓 ●防止表单域拖拽 4.2鼠标样式cursor li {cursor: pointer; }设置或检索在对象上移动的鼠标指针采用何种系统预定义的光标形状。 4.3轮廓线outline…

排序算法第三辑——交换排序

目录 ​编辑 一&#xff0c;交换排序算法的简介 二&#xff0c;冒泡排序 冒泡排序代码&#xff1a;排升序 三&#xff0c;快速排序 1.霍尔大佬写的快速排序 2.挖坑法 3.前后指针法 四&#xff0c;以上代码的缺陷与改正方法 三数取中 三路划分&#xff1a; 五&#…

【电子学会】2023年05月图形化四级 -- 计算圆的面积和周长

计算圆的面积和周长 编写程序计算圆的面积和周长。输入圆的半径&#xff0c;程序计算出圆的面积和周长&#xff0c;圆的面积等于3.14*半径*半径&#xff1b;圆的周长等于2*3.14*半径。 1. 准备工作 &#xff08;1&#xff09;保留舞台中的小猫角色和白色背景&#xff1b; 2…

Python 列表 sort()函数使用详解

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 sort函数使用详解 1、升序降序2、sort()和sorted()的区别3、切片排序4、指定排序…

TypeScript笔记

文章目录 什么是TS前期准备安装TSTS配置文件 基础类型原始类型 object类型 数组类型 元组类型 枚举 函数类型可选参数和默认参数剩余参数 any任意类型 高级类型交叉类型联合类型 接口类泛型类型别名参考 什么是TS 官网介绍&#xff1a;TypeScript是JavaScript类型的超集&#…

飞书ChatGPT机器人 – 打造智能问答助手实现无障碍交流

文章目录 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 前言 在飞书中创建chatGPT机器人并且对话&#xff0c;在下面操作步骤中…