百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

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

toyiye 2024-05-19 19:35 15 浏览 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等方面。

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

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码