🧑‍🏫
liualexiang
  • Introduction
  • Azure
    • AKS Basic
    • AKS Spark
    • AZ ACR SYNC
    • Azure CMI SDWAN
    • Azure LB DeepDive
      • Azure LB DeepDive
    • Azure Service Principal Basic
    • Azure Internal VM Network Connectivity
      • Azure Internal VM Network Connectivity
    • Azure Cli Build
    • Azure Vm Memory Monitor
  • Blockchain
    • BTC
  • CRISPR
    • 使用Parallel_Cluster提升CRISPA效率
  • OpenSource
    • ElasticSearch
      • ES Get Started
      • ES Search Query
      • Kibana 可视化
      • Logstash配置
    • Ansible 基础
    • Infra As Code
      • Pulumi Get Started
      • Terraform Basic
    • ZooKeeper 基础
    • RPC与REST
    • 使用Python申请大量内存测试
    • 使用TPC_DS产生压测数据
    • Superset
      • Superset部署手册
    • 代码扫描
    • Git
      • Git Basic
      • Github Action Basic
      • Gitlab与AzureAD集成
      • Gitbook 基础教程
    • K8S
      • enter_node
      • K8s X509 Client Cert
      • K8s Basic
      • K8s Oidc
      • Docker 基础
      • helm基础
      • K8S_Secrets管理
      • 深入了解K8S
      • 混沌工程
      • Istio
      • 生态
      • CRD开发
      • k8s网络
    • Cloud_Custodian
    • Jenkins Basic
    • Nginx
    • ETCD
    • 正则
    • VictoriaMetrics
    • Kafka
  • MySQL
    • MySQL 调优
  • Linux
    • SSH Tunnel 上网
    • 内存管理
    • 在Linux系统中通过LUKS加密磁盘
    • 量子计算 Basic
    • IO多路复用
    • Iptables
    • tmux和screen
    • Systemd
    • OS 基础
    • jq基础
    • yum
    • neovim
  • Web
    • Html Css
    • Web部署
    • 缓存
  • Programming
    • 算法
      • 返回list中最大生序子序列长度
    • Python技巧
      • Python的语法糖
      • Python常用装饰器
      • AsyncIO基础
      • 自动化测试pytest
      • python中的下划线
      • 面向对象
      • Python的坑
      • Python配置文件管理
      • HTTP Stream Response
      • Python项目管理
    • 设计模式
      • 设计模式
      • 面向对象的思想
      • 编程概念
    • Go
      • Go 基础
      • Go常用功能
      • 结构体入门
    • 前端
    • Vue
    • NodeJS
  • Math
    • 多项式插值法
  • Security
    • HTTP常见攻击
    • 加密与签名
    • RSA
    • ECDSA
  • Solidity
    • Solidity基础
    • Blockchain Testnet Faucet
  • Tools
    • 视频处理ffmpeg
    • IDE配置
    • iTerm2美化
    • 密码管理
    • FRP配置
    • 工具集
由 GitBook 提供支持
在本页
  • Go 基础语法
  • package
  • Go 模块下载
  1. Programming
  2. Go

Go 基础

Go 基础语法

Go 程序的入口的package 和函数名,必须都是 main。如果是一个包,包里函数小写开头,只能在这个包内使用,大写开头,则包内包外都可以使用。

循环

package main

import (
	"fmt"
)

func main() {
		for i := 1; i <= 9; i++ {
			for j := 1; j <= i; j++ {
				fmt.Printf("%d*%d=%d\t", j, i, i*j)
			}
			fmt.Println()
		}
}

如果是字符串、数组、slice、map或 channel的遍历,可以用 range 来进行遍历

package main

import (
	"fmt"
)

func main() {
	str := "sdfajlskfa"
	for i, c := range str {
		fmt.Printf("%c", c)
		fmt.Printf("%d,", i)
	}

	result1, result2 := add(2, 3)
	fmt.Print(result1, result2)
}

func add(a, b int) (int, int) {
	return a + b, a * b
}

如果是可变参数,可以在参数类型前加上 ...

package main

import (
	"fmt"
)

func main() {
	sum := 0
	sum = getSum(1, 2, 3)
	fmt.Println("sum result: ", sum)
}

func getSum(num ...int) int {
	sum := 0
	for i := 0; i < len(num); i++ {
		sum += num[i]
	}
	return sum
}

可变参数也是支持不确定类型的参数,示例:

func printType(args ...interface{}) {
	for _, arg := range args {
		switch arg.(type) {
		case int:
			fmt.Println(arg, " type is int")

		case string:
			fmt.Println(arg, " type is string")

		default:
			fmt.Println(arg, " type is unknown")
		}
	}
}

如果是在一个list后面加 ... 则表示解序列,示例:

var s []string  
s = append(s, []string{"a", "b", "c"}...)  
fmt.Println(s)

数据类型:列表和切片

数组 array 和 slice 切片的区别: 数组是固定长度,slice是可变长度。如果改变了数组里的值,那实际上是修改的拷贝后的数组的值,原数组值不变。但如果改了slice的值,那么直接改变的就是原始slice。

arr := [4]int{1,2,3,4}
sli := []int{1,2,3,4}

匿名函数

直接 func() 不给函数起名,就是匿名函数,匿名函数也可以接受参数,也可以有返回值,一个示例:

r := func(a, b int) int {  
    return a + b  
}(3, 5)  
  
fmt.Println(r)

函数式编程

回调函数

将函数作为另外一个函数的参数,这个函数是回调函数,调用方是高阶函数。示例 add 就是回调函数

func main() {  
    addR := operator(3, 4, add)  
    fmt.Println(addR)  
}  
  
func operator(a, b int, f func(int, int) int) int {  
    r := f(a, b)  
    return r  
}  
  
func add(a int, b int) int {  
    return a + b  
}

闭包

当内层函数使用外层函数的变量,外层函数销毁了,但内层函数还在执行,此时变量依然能用。这种结构就叫做闭包。在支持回调函数的程序语言里,一般都是支持闭包

值传递和引用传递

如果是值传递,那么传过去的函数里,拿到的是副本,对其修改不会作用到原来调用方。如果是引用传递,则传递过去的修改,会作用于本身。不过需要注意的是:如果在引用的函数里,对这个变量重新赋值,则即使是引用传递,也不会作用于原函数里。 值传递的数据类型: int、string、bool、float64、array 引用传递的数据类型: slice、map、chan

举一个例子:下面定义的 l1 是一个 slice(因为没有定义list长度),所以是引用传递。也就意味着,当在调用的函数里修改了这个值,则这个变量的内存地址里的值被修改,所以在原始main函数里,执行函数后的值也发生了变化

func main() {  
    l1 := []int{1, 2, 3, 4}  
    fmt.Println("传入前的值", l1)  
    updateList(l1)  
    fmt.Println("执行函数后的值", l1)  
}  
  
func updateList(l2 []int) {  
    fmt.Println("接收到的值\t", l2)  
    l2[0] = 100  
    fmt.Println("修改后的值\t", l2)  
}

但同样的代码,我们把 l1 定义的时候,指定长度为4,定义为 array 列表,此时就是值传递,即使调用了某一个函数传了这个值,在调用函数内部做的修改,并不会反应到原始函数上。

func main() {  
    l1 := [4]int{1, 2, 3, 4}  
    fmt.Println("传入前的值", l1)  
    updateList(l1)  
    fmt.Println("执行函数后的值", l1)  
}  
  
func updateList(l2 [4]int) {  
    fmt.Println("接收到的值\t", l2)  
    l2[0] = 100  
    fmt.Println("修改后的值\t", l2)  
}

package

  1. 如果包里的函数名是小写字母开头,只能在包内使用。

  2. 一个包内只能有一个 init() 函数,这个函数会在import的时候生效。

  3. 包是可以匿名导入的, 在匿名导入的时候,只会执行 init()函数。导入方法是

import _ packageName
  1. 在调用包的时候,可以给包起一个别名。如果别名是 . 则可以直接用这个包里的函数,比如 fmt.Println 如果import的时候别名是 . ,那么就可以直接用 Println()了,而不是 fmt.Println()

import (
. "fmt"
)

Go 模块下载

首先项目里要有 go.mod 文件,这个文件里包含了依赖包的信息,如果想要整理下这个文件,可以用 go mod tidy,会清理没用到的包。如果没有 go mod文件,可以初始化这个go项目。比如go代码都在当前路径的 my_project 文件夹下,那么我们用下面的命令,可以在该文件夹下创建 go.mod

go mod init my_project

之后下载包的时候用

go get github.com/ethereum/go-ethereum/crypto
上一页Go下一页Go常用功能

最后更新于7个月前