百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

《Golang入门》一篇文章学完GO的基本语法《建议收藏》

lipiwang 2025-06-13 14:44 6 浏览 0 评论

一、package

package时最基本的分发单位和工程管理中依赖关系的体现;

每个Go语言源代码文件开都都有一个package的声明,表示源码文件所属于代码包;

要生成GO语言可执行程序,必须要有main的package包,且必须在该包下有main函数;

同一个路径下只能存在一个package,一个package可以由多个源文件组成

二、import

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

import 只有一个功能,导入源代码依赖的package包,需要注意一下点:

不能导入源代码未用到的package包,否则go语言编译器会报错;

如果一个main包带入其它多个包,包将被顺序导入

如果main包中导入的包(如A包)中又依赖了其它的包(如B包),会首先导入依赖的B包,然后初始化B包中的常量和变量,如果B包中还有init函数,会自动执行init函数,当main包中的所有包导入完后,才会对main包中的常量和变量进行初始化,然后执行main包中的init函数,最后执行main包中的main函数;

如果一个包被导入多次,则该包只被导入依次;

import 有如下两种写法总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

方式一:

import "package1"
import "package2"
import "package3"
……

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

方式二:

import(
"package1"
"package2"
"package3"
……
)

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

import 还有以下常用用法:

1、别名操作:将导入的包命名为另一个容易记忆的别名;

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

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

2、点(.)操作:通过点标识导入包后,调用该包中的函数时可以省略包前缀;

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

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

3、下划线(_)操作:用下划线导入的包,不导入整个包,而是执行包中的init函数,无法通过包名来调用包中的其他函数。使用下划线操作往往是为了注册包中的引擎,让外部方便调用。

package main
import (
_ "fmt"
)
func main() {
fmt.Println("Hello World")

运行程序,报错,表示fmt未定义

# command-line-arguments
.\HelloWorld.go:7:2: undefined: fmt
1
2

三、数据类型总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

基本数据类型包括数值型、布尔型、字符串型。


总结送免费学习资料(包含视频、技术学习路线图谱、文档等)


总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

变量被声明后的默认值情况:值类型的默认值为0,布尔型的默认值为false,String类型的默认值为空。

四、高级数据类型

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

1、数组类型
一个数组只能容纳若干相同类型的元素。

var arry1 [3]int 	//声明一个int类型的数组
arry1[0] = 0
arry1[1] = 1
arry1[2] = 2
var arry2 = [3]string{"a", "b", "c"} //声明并定义数组类型
var arry3 = [...]int{4, 5, 6}	//声明定义时,没有指定长度
var num int = len(arry3)	//求数组的长度

2、切片类型
切片类型与数组类型类似,可以容纳若干数据类型相同的元素,但切片类型不是定长度,切片类型可以通过数组进行切取

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

var arry1 = [6]int{1, 2, 3, 4, 5, 6}
var slice1  = arry1[1:3]
fmt.Println(len(slice1))	//2
fmt.Println(slice1)			//[2 3]

var slice2  = arry1[1:4:6]
fmt.Println(len(slice2))	//3
fmt.Println(slice2)			//[2 3 4]

var slice3  = append(slice2, 5, 6, 7)
fmt.Println(len(slice3))	//6
fmt.Println(slice3)			//[2 3 4 5 6 7]

var slice4 = []int{0, 0, 0, 0, 0, 0}
copy(slice4, slice2)
fmt.Println(len(slice4))	//6
fmt.Println(slice4)			//[2 3 4 0 0 0]

3、字典类型
字典类型用于存储键值对,同一个字典中的每个键都是唯一的。如果我们在向字典中放入一个键值对的时候其中已经有相同的键的话,那么与此键关联的那个值会被新值替换。

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

/*int键类型,string表示值类型*/
map1 := map[int]string{1:"a", 2:"b", 3:"c", 4:"d", 6:"f"}
/*6为键*/
value1 := map1[6]
fmt.Println(value1) //f
map1[5] = "e"
value5, ok := map1[5]
fmt.Println(value5) //e
fmt.Println(ok) //true
/*删除键*/
delete(map1, 6)
fmt.Println(map1) //map[1:a 2:b 3:c 4:d 5:e]

4、函数类型
go语言中函数由func关键字表示,在go语言中可以把函数赋给一个变量,通过变量来调用函数,例如 type myFunc my_func(s1 string, s2 string) string。常用形式如下:

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

package main

import "fmt"

func myfun(s1 string, s2 string) string {
	return  s1 + s2
}

func myfun1(s1 string, s2 string) (result string) {
	result = s1 + s2
	return  result
}

func myfun2(s1 string, s2 string) (int, string) {
	result := s1 + s2
	num := len(result)
	return num, result
}

func main()  {
	s := myfun("hello ", "world")
	fmt.Println(s)		//hello world

	s1 := myfun1("hello ", "china")
	fmt.Println(s1)		//hello china

	num, s2 := myfun2("hello ", "lzj")
	fmt.Println(num)	//9
	fmt.Println(s2)		//hello lzj
}

5、指针
go语言中指针表示形式与C语言中的类似,都是通过"*“获取地址中的值,通过”&"获取地址,用法如下:
用法一(同C写法):

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

package main

import "fmt"

type Person struct {
	name string
	age int
}

func increaseAge(num int, person *Person)  {
	(*person).age = (*person).age + num
}

func increaseAge2(num int, person Person)  {
	person.age = person.age + num
}

func main()  {
	var p1  *Person
	var p2  Person
	p1 = &Person{"lzj", 25}
	/*p1是一个指针,下面把该指针的副本传递给了increaseAge函数,
	p1的副本与p1同指向一个内存位置,所以p1的副本在increaseAge方法中修改了值,
	那么p1中的值也被修改了
	*/
	increaseAge(3, p1)	//方法中改变了p1的值
	fmt.Println((*p1).age)		//28

	/*p2是非指针类型的变量,下面把p2的值得副本传递给了increaseAge2函数
	p2的副本值改变了,但不影响p2的值,因为p2的副本仅是p2值得一个copy
	*/
	p2 = Person{"Bob", 20}
	increaseAge2(5, p2)	//方法未改变p2的值
	fmt.Println(p2.age)			//25
}

用法二:总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

package main

import "fmt"

type Person2 struct {
	name string
	age int
}

/*接受者类型是指针,称该方法为指针方法*/
func (person *Person2) increaseAge(num int){
	/*也可以写成person.age,会自动把person理解为指针的*/
	(*person).age = (*person).age + num
}

/*接受者类型为原型,称该方法为值方法*/
func (person Person2) increaseAge2(num int){
	person.age = person.age + num
}

func main()  {
	var p1 *Person2
	p1 = &Person2{"lzj", 25}
	p1.increaseAge(3)
	fmt.Println((*p1).age)

	var p2  Person2
	p2 = Person2{"Bob", 20}
	p2.increaseAge2(3)
	fmt.Println(p2.age)
}

6、interface总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

interface时一种类型,时拥有一组方法的类型,用type来定义。如果一个类型实现了interface中的所有方法,那么该类型是interface的一个实现类。interface类型可以没有方法,是一个empty interface,任何类型都是empty interface的实现类。

package main

import "fmt"

type I interface {
	Get() int
	Set(int)
}

type S struct {
	Age int
}

func(s S) Get()int {
	return s.Age
}

func(s *S) Set(age int) {
	s.Age = age
}

func f(i I){
	i.Set(10)
	fmt.Println(i.Get())	//输出10
}

func main() {
	s := S{}
	f(&s)
}

7、struct类型总结送免费学习资料(包含视频、技术学习路线图谱、文档等)
Go语言中struct类型与C类似,但比C中的更灵活,可以为struct类型实现新的方法。

package main

import "fmt"

type Student struct {
	name string
	age int
}

/*可以为student类型添加方法*/
func (student *Student) increaseAge(num int) {
	(*student).age = (*student).age + num
}

func main()  {
	/*创建一个Student类型的值时,可以按顺序写,省略内部字段名*/
	student := Student{"lzj", 25}
	(&student).increaseAge(3)
	fmt.Println(student.age)		//28

	/*创建一个Student类型的值时,也可以选择不省略字段名*/
	student2 := Student{name:"Bob", age:20}
	(&student2).increaseAge(3)
	fmt.Println(student2.age)		//25
}

四、变量总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

全局变量的声明必须使用var关键词,局部变量可以省略;同一行可以声明多个变量。写法如下:

package main
import (
	"fmt"
)
/*变量声明赋值*/
var i1, i2, i3 int = 1, 2, 3
var(
	a string = "hello world"
	b int
)
func main()  {
	/*局部变量可以写成组的形式*/
	var(
		c uint = 10
		d string = "ddd"
	)
	/*局部变量可以省略var,全局的不可以省略*/
	e,f := 4,5
	……
}

变量类型转化总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

GO中不存在隐式转换,类型转换必须是显示的,并且只能发生在两种兼容类型之间,例如:

var i1 int = 1
var i4 float32 = float32(i1)


**注意:**大写字母开头的变量是可以导出的,也就是可以被其它包读取,是公用变量;

小写字母开头的是不可导出的,是私有变量。

五、常量总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

常量范围目前只支持布尔型、数字型、字符型。常量定义从形式上可以分为显示和隐式:

显示:const const_name1 type = value
隐式:const const_name2 = value
const MY_CONSTAT1 string = "hello world"
const MY_XONSTANT2 = "HELLO CHINA"
const (
MY_CONSTANT3 string ="hello go"
MY_CONSTANT4 = "hello GO"
)
const language1,language2,language3 string = "go","java","python"


特殊常量iota的用法总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

iota在关键字const出现时被重置为0, const中每新增一行常量声明将使iota的计数加1。例如:

package main
import "fmt"
const a = iota
/*b、c、d中只出现了一次const,所以b、c、d累加1*/
const(
b = iota
c = iota
d = iota
)
func main() {
fmt.Println("a的值为:")
fmt.Print(a) /*a的值为0*/
fmt.Print("\n")
fmt.Println("b的值为:")
fmt.Print(b) /*b的值为0*/
fmt.Print("\n")
fmt.Println("c的值为:")
fmt.Print(c) /*c的值为1*/
fmt.Print("\n")
fmt.Println("d的值为:")
fmt.Print(d) /*d的值为2*/
fmt.Print("\n")

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

iota的常见用法:

1、跳值使用法

package main
import "fmt"
const a = iota
const(
b = iota
c = iota
/*用_把2跳过去*/
_ = iota
d = iota
)
func main() {
fmt.Println("a的值为:")
fmt.Print(a) /*a的值为0*/
fmt.Print("\n")
fmt.Println("b的值为:")
fmt.Print(b) /*b的值为0*/
fmt.Print("\n")
fmt.Println("c的值为:")
fmt.Print(c) /*c的值为1*/
fmt.Print("\n")
fmt.Println("d的值为:")
fmt.Print(d) /*d的值为3*/
fmt.Print("\n")
}

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

2、插队使用法

package main
import "fmt"
const(
b = iota
/*c插入b和d之间,b=0, d=2*/
c = 5.12
d = iota
)
func main() {
fmt.Println("b的值为:")
fmt.Print(b) /*b的值为0*/
fmt.Print("\n")
fmt.Println("c的值为:")
fmt.Print(c) /*c的值为5.12*/
fmt.Print("\n")
fmt.Println("d的值为:")
fmt.Print(d) /*d的值为2*/
fmt.Print("\n")
}

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

3、表达式隐式使用法

package main
import "fmt"
const(
b = iota * 2
/*c和d隐式的继承iota * 2*/
c
d
)
func main() {
fmt.Println("b的值为:")
fmt.Print(b) /*b的值为0*/
fmt.Print("\n")
fmt.Println("c的值为:")
fmt.Print(c) /*c的值为2*/
fmt.Print("\n")
fmt.Println("d的值为:")
fmt.Print(d) /*d的值为4*/
fmt.Print("\n")
}

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

4、单行使用法

package main
import "fmt"
const(
/*iota在同一行不累加1,所以a=0, b=0+4=4*/
a, b = iota, iota + 4
/*c, d隐式继承a,b的格式,c=1, d=1+4=5*/
c, d
/*e等于2,注意e必须赋值,因为e不能隐式继承,因为格式不同*/
e = iota
)
func main() {
fmt.Println("a的值为:")
fmt.Print(a) /*a的值为0*/
fmt.Print("\n")
fmt.Println("b的值为:")
fmt.Print(b) /*b的值为4*/
fmt.Print("\n")
fmt.Println("c的值为:")
fmt.Print(c) /*c的值为1*/
fmt.Print("\n")
fmt.Println("d的值为:")
fmt.Print(d) /*d的值为5*/
fmt.Print("\n")
fmt.Println("e的值为:")
fmt.Print(e) /*e的值为2*/

fmt.Print("\n")

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

六、流程控制

1、if条件判断

示例一:

package main
import "fmt"
func main() {
var num int = 10
if num > 10{
fmt.Println("num is bigger than 10")
}else {
fmt.Println("num is not bigger than 10")
}
}


实例二:总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

package main
import "fmt"
func main() {
var num int //默认值为0
if num := 20; num > 10{ //此地的num为if模块的局部变量,只在if模块使用,会覆盖全局的num值
fmt.Println("num is bigger than 10") //此地num值为20
}else {
fmt.Println("num is not bigger than 10") //此地num值为20
}
fmt.Println("num 的值为:")
fmt.Println(num) //此地打印出的num为全局的num,值为0
}

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

2、switch条件语句

go语言的switch…case语句中,只要匹配到case中一条,就只执行该case,执行完就自动跳出,不像C语言需要在每个case执行完加break语句,否则会继续向下执行其它case语句。

示例一:总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

package main
import "fmt"
func main() {
var str string = "c"
switch str {
case "a":
fmt.Println("str的值为a")
case "b":
fmt.Println("str的值为b")
case "c": //只执行该case
fmt.Println("str的值为c") //输出:str的值为c
default: //当没有一个case满足时,执行
fmt.Println("str的值为其它")
}
}

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

示例二:

package main
import "fmt"
func main() {
var str string = "c" /*c为全局变量,值为c*/
switch str := "b"; str { //局部变量str的值为b,会覆盖全局变量的c
case "a":
fmt.Println("str的值为a")
case "b":
fmt.Println("str的值为b") //str的值为b
case "c":
fmt.Println("str的值为c")
default:
fmt.Println("str的值为其它")
}
fmt.Println(str) //c 局部变量的值并不会改变全局的值,所以str的值依旧为c
}

示例三:case 说明符
package main
import "fmt"
func main() {
var num int = 10
switch i := interface{}(num).(type){
case int8 :
fmt.Println(i)
fmt.Println("num的类型为int8")
case int16:
fmt.Println(i)
fmt.Println("num的类型为int16")
case int32:
fmt.Println(i)
fmt.Println("num的类型为int32")
case int64:
fmt.Println(i)
fmt.Println("num的类型为64")
case int:
fmt.Println(i) //10
fmt.Println("num的类型为int") //num的类型为int
default:
fmt.Println("num其它类型")
}
}

3、for语句
示例1:循环输出
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Println(i)
}
}

示例二:for语句中用range
range每次迭代都会返回两个值,一个是索引,一个索引处所代表的值
package main
import "fmt"
func main() {
var str string = "GO语言"
for i,c := range str{
fmt.Printf("%d : %c\n", i, c)
}
}

输出:
0 : G
1 : O
2 : 语
5 : 言

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

因为go语言中所有字符和汉字都是用utf-8进行编码的,一个汉字占3个字节,range返回的“语”和“言”都是第一个字节作为索引。

range可以迭代字符串类型,数组类型,数组的指针类型,切片类型,字典类型,通道类型。

对于字符串类型,数组类型,数组的指针类型,切片类型,range每次迭代出两个值,第一个代表迭代处的索引,第二个值代表迭代处的值;

对于字典类型,range每次也迭代出两个值,第一个代表键,第二个代表键对应的内容,注意迭代不能保证顺序;

for语块中可以用break或continue,用法通C语言。

七、异常处理总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

Go 语言通过内置的错误接口提供了非常简单的错误处理机制,error类型是一个接口类型,这是它的定义:

type error interface {
Error() string
}
在实际应用中,可以抛出系统的异常,也可以抛出指定的异常,示例如下:
package main
import (
"errors"
"fmt"
"os"
)
func isFileExist(path string) (bool, error) {
if path == "" {
return false, errors.New("传入路径为空") //返回自定义的错误
}
_, err := os.Stat(path)
if err != nil {
return true, err //返回系统的错误
}
return false, errors.New("未知的错误") //返回自定义的错误
}
func main() {
path := ""
flag, err := isFileExist(path)
fmt.Println(flag) //输出:false
fmt.Println(err.Error()) //输出:传入路径为空

总结送免费学习资料(包含视频、技术学习路线图谱、文档等)

也可以自己实现Error接口,并自定义错误,示例如下:
package main
import "fmt"
type My struct {
age int
}
func (my *My) Error() string {
str := `除数不能为0: %d / 0`
return fmt.Sprintf(str,(*my).age)
}
func divideError(my1 *My, my2 *My) (result int, erroMsg string) {
if my2.age == 0 {
return 0, my1.Error()
}else {
return my1.age / my2.age, ""
}
}
func main() {
var my1 *My
var my2 *My
my1 = &My{25}
my2 = &My{0}
num, err := divideError(my1, my2)
fmt.Println(num) //输出:0
fmt.Println(err) //输出:除数不能为0: 25 / 0
}


总结:比如my1是struct类型的指针,调用内部元素时,可以通过(*my1).age,也可以通过my1.age,因为go会自动进行类型推断

更多学习资料(包含视频、技术学习路线图谱、文档等)

技术点包含了C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等方面。

后台私信《资料》免费领取

相关推荐

Go语言图书管理RESTful API开发实战

Go(Golang)是最近流行起来,且相对较新的编程语言。它小而稳定,使用和学习简单,速度快,经过编译(原生代码),并大量用于云工具和服务(Docker、Kubernetes...)。考虑到它所带来的...

轻松搞定Golang 中的内存管理(golang设置内存大小)

除非您正在对服务进行原型设计,否则您可能会关心应用程序的内存使用情况。内存占用更小,基础设施成本降低,扩展变得更容易/延迟。尽管Go以不消耗大量内存而闻名,但仍有一些方法可以进一步减少消耗。其中一...

golang实现deepseek 聊天功能(golang deepcopy)

在搭建完deepseek环境后在docker内部署deepseekrag环境,我们可以用golang实现聊天功能。在实现这个功能之前,我们先了解下提示词工程(prompt)。大模型虽然知道的东西多...

golang slice的扩容机制(golang设置内存大小)

在Go语言中,切片(slice)是一种动态数组,其长度可以在运行时改变。当向切片中添加元素时,如果切片的容量不足以容纳新元素,就会触发扩容机制。下面详细介绍Go语言切片的扩容机制。扩容触发条件...

Etcd服务注册与发现封装实现--golang

服务注册register.gopackageregisterimport("fmt""time"etcd3"github.com/cor...

嘿,轻松获取区间内所有日期的Golang小技巧!

在Go语言中,获取两个日期之间的所有日期可以手动实现一个函数来完成。以下是一个示例函数,它会返回一个日期切片,包含从开始日期到结束日期(包括这两个日期)的所有日期:packagemainimpo...

仓颉、Java、Golang性能测试——数组扩容

版本信息仓颉版本0.53.18Golang版本1.22.8Java版本corretto-1.8.0_452源码仓颉packagecangjie_testimportstd.collect...

Golang 58个坑 – 中级篇:36-51(golang cef)

36.关闭HTTP的响应体37.关闭HTTP连接38.将JSON中的数字解码为interface类型39.struct、array、slice和map的值比较40.从panic...

一篇文章学会golang语法,golang简明教程快速入门

Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。——Go-wikipedia.org1Go安装最新版本下载地址官方下载https...

运维大神如何使用 Golang 日志监控应用程序

你是如何使用Golang日志监控你的应用程序的呢?Golang没有异常,只有错误。因此你的第一印象可能就是开发Golang日志策略并不是一件简单的事情。不支持异常事实上并不是什么问题,异常在...

Golang操作elasticsearch(golang操作word)

简介开源的Elasticsearch是目前全文搜索引擎的首选,很多日志都是放到elasticsearch里面,然后再根据具体的需求进行分析。目前我们的运维系统是使用golang开发的,需要定时到e...

一文带你看懂Golang最新特性(golang x)

作者:腾讯PCG代码委员会经过十余年的迭代,Go语言逐渐成为云计算时代主流的编程语言。下到云计算基础设施,上到微服务,越来越多的流行产品使用Go语言编写。可见其影响力已经非常强大。一、Go语言发展历史...

Golang 最常用函数(备用查询)(golang函数和方法)

hello.gopackagemainimport"fmt"funcmain(){fmt.Println("Hello,world!")}直...

Golang:将日志以Json格式输出到Kafka

在上一篇文章中我实现了一个支持Debug、Info、Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手。有兴趣的可以通过这个链接前往:https://github.com/...

如何从 PHP 过渡到 Golang?(php转go需要多久)

我是PHP开发者,转Go两个月了吧,记录一下使用Golang怎么一步步开发新项目。本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去...

取消回复欢迎 发表评论: