go之基本类型与函数使用
go之基本类型与函数使用
一、go语言介绍
1 go语言介绍
Go 即Golang,是Google公司2009年11月正式对外公开的一门编程语言,特点:语法简单,速度快。
Go是静态(编译型)强类型语言,是区别于解析型语言的弱类型语言(静态:类型固定 强类型:不同类型不允许直接运算)。
python动态强类型语言。
编译型语言:Java,c,c++,c#,go
解释性语言:python,js,php...
编译型语言涉及到跨平台问题,因为它需要编译成该平台的可执行文件。比如:java运行在jvm之上。go语言可以进行跨平台编译,即交叉编译。比如,从windows上编译成linux上的可执行文件。
解释性不涉及跨平台问题,因为各个平台有各个平台的解释器。
2 go语言特性
- 跨平台的编译型语言,交叉编译
- 管道(channel),切片(slice),并发(routine)
- 有垃圾回收的机制
- 支持面向对象和面向过程的编程模式(go的面向对象中没有类的概念,python是完全的面向对象)
3 go的历史发展
- 2009年11月7日 weekly.2009-11-06 —— 早期的版本
- 2015年8月19日 go1.5 —— 实现的架构变化,同时保留了和旧版本的兼容性,本次更新中移除了”最后残余的C代码”。(从此以后,自举,自己写自己)
- 2018年8月24日 go 1.11 :增加了modules,包管理
- 2020 年 8 月 go 1.15
4 go语言的应用领域
Google、Facebook、腾讯、七牛云
go语言书写:docker、k8s、蓝鲸...
应用领域:服务开发、并发、分布式、微服务等方向。
二、go语言开发环境
1 go环境配置
- IDE(Goland): 集成开发环境。
- 开发环境:sdk【一路下一步即可】
- go语言不需要手动添加到环境变量(python、java需要)
go version
: 打印go的版本信息
注意事项:
-
goland创建项目:需要选择go sdk的安装路径【默认被选中】。
-
指定gopath:代码必须放到该路径下,否则无法执行。【默认会在环境变量中创建GOPATH,需要手动自定义进行修改】。同时,所有的go代码必须放在这个路径下的src文件夹下,否则无法执行【E:Go_projectsrc项目名】。
-
路径和文件都不要出现中文。
2 go常用命令
go version // 查看go的版本信息 go env // 查看go的环境变量 - GO111MODULE=on // 使用了go.mod模式 - GOPATH=E:Go_project // 代码存放路径 - GOROOT=D:golang // go sdk安装路径 - ... go build // 编译。编译型语言,需要先编译再执行,编译成可执行文件 go run // 编译并执行。两步并作一步 go clean // 清除编译后的可执行文件 go fmt // 格式化代码【没用】 go get // 下载并安装包和依赖等同于pip install ...
三、第一个hello world
//单行注释 /*多行注释*/ 编译型语言: - 编译: go build .test01.go - 执行: .test01.exe - 编译并执行: go run .test01.go
package main // 声明包名,包名是main import "fmt" // 内置包 // 定义了一个main函数,go项目运行的入口【所以编译型语言必须有一个入口】 func main() { fmt.Println("hello world") // 等同于python中的print(python中的print是内置函数) }
注意:每个go文件都要有一个包名,代表其属于某个包。
goland中文件执行有file、package等几种方式。【可以自己进行配置,一般一个项目中使用package即可,测试的时候使用file就行】
四 变量
1 变量定义
-
var 变量名 变量类型 = 变量值
var age int = 10
go中变量定义了就必须使用,如果不适用就报错。
-
var 变量名 = 变量值
类型推导(可以不写类型)var age = 10
package main import "fmt" // 内置包 func main() { var age int = 10 var name string = "YangYi" fmt.Printf("%Tn", age) // int (看类型,没有python中的type方法,没有自动换行,需要手动n) fmt.Printf("%Tn", name) // string fmt.Print() // 打印不换行 fmt.Println() // 打印换行 fmt.Printf("%Tn", name) // 查看类型 fmt.Printf("%p", &name) // 0xc0000881e0 }
go中变量类型一旦定义,后期不能改变。(编译型语言通用,python中可以修改,python中存放的内存地址,所以可以改变类型)
-
变量名 := 变量值
简略声明(类型和var关键字都不写)a := 10
a := 10 var a int = 100 var a = 99 // 重复定义,报错(变量不可以重复定义,同时,变量必须先定义,后使用)
/* 只定义,不赋值 */ var a int // 可以(只能用这种方式) var a // 不可以(因为没有类型,不知道a是什么,因为类型需要在定义阶段确定,且不能改)
/* 声明多个变量 */ var width, height int = 100, 50 // 第一种 var width, height = 100, 50 // 第二种 width, height := 100, 50 // 第三种 var ( name = "YangYi" // 不赋类型 age int = 29 // 赋类型 height int // 声明 )
/* 小坑 */ var a int =10 var b =99 b,a:=99,100 //这个不报错,我们觉得是重复定义,冒号左侧,只要有一个没有定义过的变量,就可以
2 变量定义规范
2.1 变量命名规范
变量命令建议用驼峰(大小写有特殊意义【私有和公有的意义】);
go文件命名建议用 下划线;(ps:python中都建议都使用下划线;java中建议都是驼峰;js中变量名驼峰)
一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母、数字或下划线;
大写字母和小写字母是不同的:Name和name是两个不同的变量;
关键字和保留字都不建议用作变量名;
2.2 go语言中的关键字
// Go语言中关键字有25个 break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var // Go语言中保留字有37个,主要对应内建的常量、类型和函数 内建常量: true false iota nil 内建类型: int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr float32 float64 complex128 complex64 bool byte rune string error 内建函数: make len cap new append copy close delete complex real imag panic recover
五 数据类型
1 基础数据类型
-
数字
// 有符号整形 int 在32位机器是int32,在64位机器是int64 int8 表示整数范围是:8个比特位,8个bit是1byte ,负数和0, 2的7次方-1 的范围 int16 2的15次方减一 int32 int64 /* 强类型举例: var a int8 = 10 var b int16 = 20 fmt.Println(a + b) // 报错【go是强类型,其中没有java中的自动类型转换一说】 fmt.Println(int16(a) + b) */ /* byte:是int8的别名 单引号包裹 rune:是int32的别名 单引号包裹 */ var a byte = 99 // int8 fmt.Println(a) var b byte = 'b' // 存放的是字符,其中也是数字而已 fmt.Println(b) // 98 var c rune = '你' // 可以打印,字符中其实是数字 fmt.Println(c) // 20320 var d byte = '你' fmt.Println(d) // 报错,超出范围 // 无符号整形 uint8 2的8次方减一 (定义一个人的年龄) uint16 uint32 uint64 // 浮点数(小数),表示小数点后长度多少位 float32 float64 // 复数 complex64 complex128 var a complex64 = 20 + 10i
-
字符串
"双引号包裹" `反引号包裹` // 和js一样; python中是 """ """
-
布尔类型
bool true 和 false var flag bool = false var flag = true
数据类型默认值:数字类型是0, 字符串类型是空字符串,布尔类型是false。
java | go |
---|---|
byte | int8 |
short | int16 |
int | int32 |
long | int64 |
float | float32 |
double | float64 |
2 常量
go中常量定义使用const
关键字;java中的常量为final
关键字;python中是大写
。
-
const 变量名 变量类型 = 变量值
const name string = "yangyi" // 常量可以定义之后不使用,不会报错
-
const 变量名 = 变量值
const age = 90
-
其他定义方式
const name, age = "yangyi", 18 const ( name string = "yangyi" age = 18 ) // 应该不会使用吧 const ( s1 = iota s2 s3 = iota s4 = 99 s5 ) fmt.Println(s1) // 0 fmt.Println(s2) // 1 fmt.Println(s3) // 2 fmt.Println(s4) // 99 fmt.Println(s5) // 99 太奇怪 const ( s1 = iota s2 s3 = iota s4 = 99 s5 = iota ) fmt.Println(s1) // 0 fmt.Println(s2) // 1 fmt.Println(s3) // 2 fmt.Println(s4) // 99 fmt.Println(s5) // 4 太奇怪
六 函数
1 函数基础
func 函数名(参数名 类型, 参数名 类型)(返回值类型, 返回值类型){ 函数体内容 return 返回值1, 返回值2 }
函数使用示例
// 1 有参数无返回值 func add(a int, b int){ fmt.Println(a + b) } add(100, 200) // 调用函数 // 2 有参数无返回值,有多个相同类型的参数 func add(a, b int){ fmt.Println(a + b) } // 3 有参数无返回值,有多个不同类型的参数 func add(a, b int, msg,name string){ } // 4 多个参数,一个返回值 func add(a, b int) int { return a + b } // 5 多个参数,多个返回值【python和go支持多返回值】 func add (a, b int) (int, int){ return a + b, a * b } a, b := add(100, 200) // 多返回值就需要用多变量进行接受【和python一样】 a, _ := add(3, 4) // python中的下划线可以打印,但是go中就是空 // 6 命令返回值 func add(a, b int) (c int, d int){ c = a + b // 就是在函数体中已经声明了c d的变量 d = a * b return // 就会直接将c d返回出去,不需要写 return c,d }
2 函数高级
函数是一等公民,函数可以赋值给变量【python中也是如此】
在编译型语言中,和解释性语言不同,没有先定义函数,后使用函数一说,编译之后都能找到。
// 匿名函数(定义在函数内部,不能有名字): python中是lamdba // 第一种 func (){ }() // 匿名函数直接调用 // 第二种 var a func() // 定义一个变量,类型为func()【哈哈】 a = func(){ // 此时a是一个函数 fmt.Println("我是匿名函数") } a() // 我是匿名函数
// 7 函数返回值为函数 func test() func(){ return func(){ fmt.Println("我是返回的函数...") } } a := test() fmt.Println(a) // 0x5451e0 【打印函数名,拿到的还是函数的内存地址】 // 8 返回值函数,返回的函数带参数 // 返回值类型必须跟返回的函数类型匹配 即 func()和func(msg string)不是一个类型 func test() func(msg string){ // 返回值类型必须跟返回的函数类型匹配 return func(msg string){ fmt.Println("我是返回的函数...") } } a := test() a("hello") // 函数调用 // 9 函数返回值为函数,返回的函数带参数,带返回值 func test() func(a, b int) int { return func(a, b int) int { return a + b } } a := test() // a的类型为 var a func(a, b int)int fmt.Println(a(2, 3)) // 10 函数参数为函数类型,返回值为带参数带返回值的函数类型 func test(f func()) func(a, b int) (int, int){ f() // f函数执行 return func(a, b int) (int, int){ f() // f函数执行 return a + b, a * b } } // 函数操作 a, b := test( func(){ fmt.Println("我是函数参数...") } )(3, 4) // 函数调用 // 或者 f := func(){ fmt.Println("我是函数参数...") } f1 := test(f) a, b := f1(3, 4) fmt.Println(a, b)
3 闭包函数
①定义在函数内部; ②对外部作用域有引用;
闭包函数其实就是多了一种对函数传参的方式。
func test(age int) func() { // age := 18 a := func(){ // 定义在函数内部 fmt.Println(age) // 对外部作用域有引用 } return a } a := test(19) a() // 闭包函数的调用【并没有传参,实际上已经有参数传递进去】 // 一般来说,函数执行完毕,参数应该被释放,但是由于闭包函数的存在,所以age一直没有被释放,有东西对其有引用。【引出内存逃逸: 正常应该被回收,其实没有被回收】 // 装饰器是闭包函数的典型应用(go语言中没有装饰器的语法糖,python中有语法糖)
4 type类型重命名
type MyFunc func() // 类型重命名 func test() MyFunc { return func(){ } } type MyFunc func(a,b int)(int,string) func test() MyFunc { return func(a,b int)(int,string) { fmt.Println("xxx") return 10,"ok" } } type Myint int // 这里Myint和int已经不是铜鼓一个类型了 var a int = 10 var b Myint = 100 fmt.Println(a + b) // 报错 fmt.Println(a + int(b)) // 强制类型转换
5 变量的作用域范围
同一个包下,函数名不能重名。比如:都在main包中
// 第一种方式 var a int //全局变量,全局有效,只要改了,就是改了 func main() { fmt.Println(a) //0 a=19 fmt.Println(a) //19 test1() //99 fmt.Println(a) //99 } func test1() { a=99 fmt.Println(a) // 99 } // 第二种方式【局部 ——> 全局 ——> 内置】 var a int //全局变量,全局有效,只要改了,就是改了 func main() { var a int fmt.Println(a) //0 a=19 fmt.Println(a) //19 test1() // 0 fmt.Println(a) //19 } func test1() { fmt.Println(a) }
推荐这些文章:
package mainimport "fmt"func Slic(q interface{}) *int { s:= q.(*int) fmt.Println(*s) switch v:= q.(type) { case *int: fmt.Println(*v) case string: fmt.Println(v) default: fmt.Println("is not type!") } return nil}func main() { var i int Slic(&i)
00
进程 已完成,退出代码...
package main
import "fmt"
func main() {
arr := [10]int{} //数组
arr[1] = 8
fmt.Println(arr)
arr2 := [2][3]string{{"1", "2", "3"}} //二维数组
arr2[1][0] = "4"
arr2[1][1] = "5"
arr2[1][2] = "5"
fmt.Println(arr2)
s := []string{"你好", "再见"} //切片(代表内存地址,地址传递)
s = ap...
package main
import "fmt"
func main() {
// 变量定于的语法格式
// 常规写法
var age int
age = 30
fmt.Println(age)
// 简化
var name string = "paul"
fmt.Println(name)
// 类型推断
var float1 = 13145.20
fmt.Printf("%f,%T",float1, float1)
// 简短写法,只能在函数中使用
r...
字符串数组
package main
import (
"fmt"
)
func main() {
var str string
str = "hello world"
ch := str[0]
fmt.Printf("the length of\"%s\" is %d \n", str, len(str))
fmt.Println("the first character of\"%s\"is %c.\n", str, ch)
}
基本变量
package main
import (
"fmt"
)
func main() {
/*变量使用
var v1, v2...
package main
import (
"fmt"
)
type Animal interface {
Talk()
Eat()
Name() string
}
type Dog struct {
}
func (d Dog) Talk() {
fmt.Println("汪汪汪")
}
func (d Dog) Eat() {
fmt.Println("我在吃骨头")
}
func (d Dog) Name() string {
fmt.Println("我的名字叫旺财")
return "旺财"
}
type Pig struct {
}
func (d Pig) Talk() {
f...
/* 函数也是一种类型 */
package main
import (
"fmt"
)
/* 自定义函数类型 接受两个int参数,返回int类型*/
type op_func func(int, int) int
func main() {
test_func()
}
func test_func() {
/* 声明变量c 类型为自定义类型 */
var c op_func
/* add函数赋值给c add函数接受两个int参数,返回int类型 */
c = add
sum := c(100, 103)
fmt.Println(sum)
/* 调用自定义函数,传...
1,在函数中修改全局变量 情况二比情况一的函数m给a赋值多了一个:
package main
import "fmt"
var a = "G"
func main() {
n()
m()
n()
}
func n() {
fmt.Println(a)
}
/* 情况一
func m() {
a = "O"
fmt.Println(a)
}
//情况一输出:
//G
//O
//O
*/
// 情况二:
func m() {
a := "O"
fmt.Println(a)
}
//情况二输出:
//G
//O
//G
写入自己的博客中才能记得长久
...
package main
import "fmt"
func calc(a , b int) (int,int){
sum := a+b
sub := a-b
return sum,sub
}
func calc1(a , b int) (sum int,sub int){
sum = a+b
sub = a-b
return
}
func calc_v1(b ...int) int{
sum := 0
for i:=0;i<len(b);i++{
sum += b[i]
}
return sum
}
func calc_v2(a int,b ...
& :返回变量的存储地址
* :取指针变量对应的数值
package main
import "fmt"
func main(){
//定义一个变量:
var age int = 18
fmt.Println("age对应的存储空间的地址为:",&age)//age对应的存储空间的地
var ptr *int = &age
fmt.Println(ptr)
fmt.Println("ptr这个指针指向的具体数值为:",*ptr)
}
...
1、接口的定义
import "fmt"
type Personer interface {
SayHello()
}
type Student struct {
}
func (stu *Student)SayHello() {
fmt.Println("老师好")
}
func main() {
//创建一个学生对象
var stu Student
//通过接口变量的方式来调用,必须都实现接口中声明的所有方法
var person Personer
person = &stu
person.SayH...
文章链接:https://www.dianjilingqu.com/623.html
本文章来源于网络,版权归原作者所有,如果本站文章侵犯了您的权益,请联系我们删除,联系邮箱:saisai#email.cn,感谢支持理解。