go相当详细的基础语法
Posted WELCOME TO ivanlee717!!!!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go相当详细的基础语法相关的知识,希望对你有一定的参考价值。
运行命令 go run xx.go
或者 go build xx.go + ./xx
package main
import (
"fmt"
)
func main()
fmt.Println("hello world")
基础语法
package main
import (
"fmt"
"math"
)
func main()
var a = "ivanlee"
var b, c int = 1, 2
var d = true
var e float64
f := float32(e)
g := a + "_regina"
fmt.Println(a, b, c, d, e, f)
fmt.Println("g=", g)
const s string = "constant"
const h = 50000000
const i = 3e20 / h
fmt.Println(s, h, i, math.Sin(i))
- 定义变量可分为:var+变量定义,变量 :=
- 定义常量时没有类型限制,其可根据上下文自行进行定义
if/else
func main()
if 7%2 == 0
fmt.Println("7%2==0")
else
fmt.Println("7%2!=0")
if num := 9; num < 0
fmt.Println("num < 0")
else if num < 10
fmt.Println("0<num<10")
else
fmt.Println("num>10")
if 条件当中的语句不需要加括号,也可以在if当中添加变量的定义
for循环
go语言当中只有for循环,没有while循环
func main()
var i int = 1
for
fmt.Println("loop")
i = i + 1
if i == 3
break
for n := 1; n < 9; n++
if n%2 == 0
continue
fmt.Println("n=",n)
for i <= 5
fmt.Println("i=", i)
i = i + 1
如果for循环当中没有条件,则相当于python里面的while True
,内部没有break则会一直执行
也可以像C++语法中的正常三个条件值进行编写,也可以提前定义变量以后进行范围操作,这一步也类似于while i<=5
。
switch
func main()
a := 2
switch a
case 1:
fmt.Println("a=1")
case 2:
fmt.Println("a=2")
case 3, 4, 5:
fmt.Println("a=3 or 4 or 5")
default:
fmt.Println("other")
t := time.Now()
switch
case t.Hour() < 12:
fmt.Println("morning")
default:
fmt.Println("afternoon")
switch分支语句的用法中可以使用任意类型的变量,也可以在case语句当中使用,并且当case被命中之后,会直接跳出当前switch,运行后面的语句
数组
var a [5]int
a[4] = 100
fmt.Println(a[4], len(a))
b := [5]int1, 2, 3, 4, 5
fmt.Println(b)
var c [2][3]int
for i := 0; i < 2; i++
for j := 0; j < 3; j++
c[i][j] = i + j
fmt.Println("2d: ", c)
定义数组时,大小必须是固定的,所以数组也并不常用。所以一般使用 切片技术,这样也就更像python的数组
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
fmt.Println(s)
fmt.Println(len(s))
s = append(s, "c")
s = append(s, "d", "f")
fmt.Println(s)
c := make([]string, len(s))
copy(c, s)
fmt.Println(c)
fmt.Println(c[2:5])
fmt.Println(c[:5])
fmt.Println(c[2:])
good := []string"g", "o", "o", "d"
fmt.Println(good)
map
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
fmt.Println(m)
fmt.Println(m["one"])
fmt.Println(m["regina"]) //没有key时会输出0
value, ok := m["regina"]
fmt.Println(value, ok)
delete(m, "two")
m2 := map[string]int"three": 3, "four": 4
var m3 = map[string]int"five": 5, "six": 6
fmt.Println(m2, m3)
make函数就是只用于定义,如果要赋值则直接在后面用进行赋值
map更像python里面的字典,可以用delete函数删除key,如果map里面没有key,则会有一个false值
range
n := []int1,2,3,4,5
sum := 0
for i, num := range n
sum += num
if num == 2
fmt.Println("index:", i, " num:", num)
m := map[string]string"a": "A", "b": "B"
for k, v := range m
fmt.Println("key:", k, " value:", v)
for k := range m
fmt.Println("key:", k)
函数
func add(a int, b int) int
return a + b
func add2(a, b int) int
return a + b
func exist(m map[string]string, k string) (v string, ok bool)
v, ok = m[k]
return v, ok
func main()
fmt.Println(add(1, 2))
fmt.Println(add2(2, 3))
fmt.Println(exist(map[string]string"a": "A", "b": "B", "A"))
fmt.Println(exist(map[string]string"a": "A", "b": "B", "a"))
函数定义时,参数需要类型定义,以及返回时的类型。如果有多个函数返回值,则分别说明类型
指针
func add(n int)
n += 2
func add2ptr(n *int)
*n += 2
func main()
n := 5
add(n)
fmt.Println(n)
add2ptr(&n)
fmt.Println(&n)
fmt.Println(n)
结构体
Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
func checkpwd(u user, pwd string) bool
if u.password == pwd
return true
else
return false
func checkpwd2(u *user, pwd string) bool
if u.password == pwd
return true
else
return false
func main()
a := username: "ivanlee", password: "regina"
b := user"ivanlee", "regina"
c := username: "ivanlee"
c.password = "regina"
var d user
d.name = "ivanlee"
d.password = "password"
fmt.Println(checkpwd(a, "zjr")) //false
fmt.Println(checkpwd2(&b, "regina")) //true
定义一个结构体之后,实例化有abcd四种赋值方法。结构体也拥有其方法,写法要更加简洁
type user struct
name string
password string
func (u user) checkpwd(pwd string) bool
return u.password == pwd
func (u *user) resetpwd(pwd string)
u.password = pwd
func main()
a := username: "ivanlee", password: "regina"
a.resetpwd("zjr")
fmt.Println(a.checkpwd("zjr")) //true
func (u user) checkpwd(pwd string) bool` 这种定义函数的方法,可以使得每一个实例化结构体的对象直接调用,把`func(a,pwd)`的写法变成了`a.func(pwd)
字符串操作
func main()
a := "hello"
fmt.Println(strings.Contains(a, "ll"))//包含
fmt.Println(strings.Count(a, "l"))
fmt.Println(strings.HasPrefix(a, "he"))
fmt.Println(strings.HasSuffix(a, "llo"))
fmt.Println(strings.Index(a, "ll"))
fmt.Println(strings.Join([]string"hel", "lo", "-"))
fmt.Println(strings.Repeat(a, 2))
fmt.Println(strings.Split("a-b-c", "-")) //得到一个数组
fmt.Println(strings.ToLower(a))
fmt.Println(strings.ToUpper(a))
fmt.Println(len(a))
字符串格式化
p := point1, 2
fmt.Printf("%+v\\n", p)
fmt.Printf("%#v\\n", p)
fmt.Printf("type: %T\\n", p)
fmt.Printf("int %d\\n", 123)
fmt.Printf("bin %b\\n", 14)
fmt.Printf("char %c\\n", 33)
fmt.Printf("hex %x\\n", 27)
fmt.Printf("float1 %f\\n", 78.9)
fmt.Printf("float2: %e\\n", 123400000.0)
fmt.Printf("float3: %E\\n", 123400000.0)
fmt.Printf("str1 %s\\n", "\\"string\\"")
fmt.Printf("str2: %q\\n", "\\"string\\"")
fmt.Printf("str3: %x\\n", "hex this")
fmt.Printf("pointer: %p\\n", &p)
fmt.Printf("width1: |%6d|%6d|\\n", 12, 345)
fmt.Printf("width2: |%6.2f|%6.3f|\\n", 1.2, 3.45)
fmt.Printf("width3: |%-6.2f|%-6.2f|\\n", 1.2, 3.45)
fmt.Printf("width4: |%6s|%6s|\\n", "foo", "b")
fmt.Printf("width5: |%-6s|%-6s|\\n", "foo", "b")
s := fmt.Sprintf("sprintf: a %s", "string")
fmt.Println(s)
fmt.Fprintf(os.Stderr, "io: an %s\\n", "error")
第3行:如果值是一个结构体,%+v
的格式化输出内容将包括结构体的字段名。
第4行:%#v
根据 Go 语法输出值,即会产生该值的源码片段
第5行:需要打印值的类型,使用 %T
第7行:格式化整型数有多种方式,使用 %d
进行标准的十进制格式化。
8-10行:分别是二进制,字符化,16进制
第11行:%f
表示浮点数
12-13行:%e
和 %E
将浮点型格式化为(稍微有一点不同的)科学记数法表示形式。
第15行:%s
表示输出字符串,如果遇到双引号,使用%q
第17行:%x
输出使用 base-16 编码的字符串, 每个字节使用 2 个字符表示。
第19行:要输出一个指针的值,使用 %p
第21行:要指定整数的宽度,请在动词 “%” 之后使用数字。 默认情况下,结果会右对齐并用空格填充。
第22行:也可以指定浮点型的输出宽度,同时也可以通过 宽度.精度
的语法来指定输出的精度。
第23行:要左对齐,使用 - 标志
第27行:Printf通过 os.Stdout
输出格式化的字符串。 Sprintf 则格式化并返回一个字符串而没有任何输出
第30行:用 Fprintf
来格式化并输出到 io.Writers
而不是 os.Stdout
json
对于一个已有的结构体,只要保证每个字段段第一个字母是大写,也就是公开字段,那么这个结构体就可以用JSON.marshaler
去序列化,变成一个json字符串。序列化之后的字符串可以通过JSON.unmarshaler
去反序列化到一个空的变量里面。
package main
import (
"encoding/json"
"fmt"
)
type user struct
Name string
Age int
Hobby []string
func main()
a := user"ivanlee", 18, []string"basketball", "math"
buf, err := json.Marshal(a)
if err != nil
panic(err)
fmt.Println(buf)
fmt.Println(string(buf))
buf, err = json.MarshalIndent(a, "", "\\t")
if err != nil
panic(err)
fmt.Println(string(buf))
var b user
err = json.Unmarshal(buf, &b)
if err != nil
panic(err)
fmt.Printf("%#v\\n", b)
- 只要是可导出成员(变量首字母大写),都可以转成json。
时间处理
time.Now
得到的当前时间的时区跟电脑的当前时区一样。time.Parse
把时间字符串转换为Time,时区是UTC时区。其中layout的时间必须是 "2006-01-02 15:04:05"****这个时间,不管格式如何,时间点一定得是这个,如:"Jan 2, 2006 at 3:04pm (MST)","2006-Jan-02"等。如换一个时间解析出来的时间就不对了,要特别注意这一点。- 不管Time变量存储的是什么时区,其Unix()方法返回的都是距离UTC时间:1970年1月1日0点0分0秒的秒数。
Unix()
返回的秒数可以是负数,如果时间小于1970-01-01 00:00:00的话。
func main()
now := time.Now()
fmt.Println(now)
t1 := time.Date(2000, 1, 27, 1, 25, 36, 0, time.UTC)
t2 := time.Date(2000, 1, 22, 1, 25, 36, 0, time.UTC)
fmt.Println(t1)
fmt.Println(t1.Year(), t1.Month(), t1.Day())
fmt.Println(t1.Format("2006-01-02 15:04:05"))
diff := t2.Sub(t1)
fmt.Println(diff)
t3, err := time.Parse("2006-01-02 15:04:05", "2022-02-10 01:23:45")
if err != nil
panic(err)
fmt.Println(t3 == t1)
fmt.Println(now.Unix())
数字和字符转换
在go语言中,字符串和数字之间的转换都存在"STR/conv"
包中,可以使用parseint
或者parseFloat
函数解析一个字符串,可以使用Atoi
函数把一个十进制的字符串转换成数字,用itoA
函数把数字转换成字符串。
f, _ := strconv.ParseFloat("1.234", 64)
//inputstring是一个用字符串表示的数字浮点数 bitSize是int类型的参数精度值。对于 float32 可以是 32,对于 float64 可以是 64
//这个函数总是返回两个值。返回的float64值包含一个浮动数。如果需要,我们可以转换为float32值。如果不能将字符串转换为浮动数,则返回错误值*NumError。
fmt.Println(f)
n, _ := strconv.ParseInt("12345", 10, 64)
//第二个参数代表进制
fmt.Println(n)
n1, _ := strconv.ParseInt("0x1000", 0, 64)
//值为2~36,如果为0,则会根据字符串自动判断前置为"0x"的是16进制;前置为"0"的是8进制;其余的为10进制
fmt.Println(n1)
n2, _ := strconv.Atoi("123")
fmt.Println(n2)
n3, err := strconv.Atoi("AAA")
fmt.Println(n3, err)
n4 := strconv.Itoa(234)
fmt.Println(n4)
进程信息
func main()
fmt.Println(os.Args)
fmt.Println(os.Getenv("PATH"))
fmt.Println(os.Setenv("AA", "BB"))
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
//command里面的参数第一个是执行命令,后面所有全部都是参数
if err != nil
panic(err)
fmt.Println(string(buf))
Getenv
函数会检索并返回名为 key 的环境变量的值。如果不存在该环境变量则会返回空字符串。
Setenv
函数可以设置名为 key 的环境变量,如果出错会返回该错误。
本文来自博客园,作者:ivanlee717,转载请注明原文链接:https://www.cnblogs.com/ivanlee717/p/17397393.html
Go Web编程实战----Go语言的基础语法
目录
前言
很高兴能够一起和大家学习Go语言,对于它的场景其实很多,包括云计算、容器虚拟化、分布式存储、网络爬虫、运维开发、Web开发、服务端开发、区块链、IoT等领域都有所应用。
今天,博主主要来详细介绍其基本的实用语法,方便读者能够快速的掌握Go语言的用法。
Hello World
程序员有一个神奇的定律,那就是Hello World。在我们每次学习新的编程语言时,都会接触到它。而Go语言的第一课,同样也从它开始。
package main
import "fmt"
func main()
fmt.Println("Hello World")
代码其实很简单,学过其他语言的应该很容易看懂。
包的声明与导入
其中,package是声明包名的关键字,“main”就是包名,这里也可以自定义。
Go语言的包,具有如下特性:
- 一个目录下的同级文件属于一个包
- 包名可以与其目录名不同
- main包是Go语言应用程序的入口包。一个Go语言应用程序必须有且仅有一个main包。如果一个程序没有main包,编译时就会报错。
而import是导入包的关键字,通过它我们能引用其他包的变量或者方法。需要注意的是,包名必须用双引号(“”)包围。
如果你想导入多个包,也可以这样写:
import(
"fmt"
"os"
)
/*起别名*/
import(
fm "fmt"
li "os"
)
运行程序方式
这里,我们可以通过编译器GoLand运行,也可以通过命令行go run “go文件名”进行控制台输出。
当然,我们还可以进行拆分,通过先编译后执行的命令行运行Hello World。代码如下所示:
go build HelloWorld.go
./HelloWorld
基础语法
Go程序由关键字、标识符、常量、字符串、符号等多种标记组成。一般来说,一行就是一个语句,但其不像Java等语言,不需要在最后用“;”结尾。
需要注意的是,如果你将多个Go语句写在一行,那么就需要使用“;”进行隔开。但官方不建议我们这样写,一行一个语句是标准,且比较易读的。
注释
Go语言的注释,其实与Java语言一模一样,也有单行注释与多行注释。其中,单行注释通过“//”声明。多行注释通过“/*”开头,"*/"结尾。具体代码如下所示:
//单行注释
/*
多行注释
*/
标识符
标识符主要用作变量、类型等程序实体进行命名。一个标识符由一个或者多个字母、数字、下划线("_")组成。需要注意的是,第一个字符不能是数字以及Go程序的关键字。
变量
在Go语言中,变量的声明语法如下:
var name type
其中,var是声明变量的关键字,name是变量名,type是变量的类型。
从这里,读者可以看出来,Go语言在声明变量时,与其他语言不同,它时将类型放在变量名称之后。
当然,有时候,一个个声明变量太麻烦,也会同时申请一大堆变量进行使用。声明多个变量的代码如下所示:
var(
name string
age int
student string
)
除var关键字外,还可以使用简短的变量定义和初始化语法,格式如下:
名字 :=表达式
//示例
name :="liyuanjing"
需要注意的是,简短模式有以下限制:
- 只能用来定义变量,同时会显式初始化
- 不能提供数据类型
- 只能用在函数内部,即不能用来声明全局变量。
下面,博主直接用多个例子,来讲解变量的赋值方式。具体代码如下所示:
//完整语法
var name string = "liyuanjing"
//自动识别类型
var name = "liyuanjing"
//多变量赋值声明
var (
name string = "liyuanjing"
age int = 29
money float32 = 22.22
)
var name,age,money="liyuanjing",29,22.22
//全局变量的声明
var global int=558
需要特别注意,如果你在某个方法中声明了变量,那么后续必须使用这个变量,不然程序就会报错。(也就是不用这个值,同样也会报错)
常量
在Go语言中,常量使用const进行声明,常量主要用于存储不会改变的值。需要注意的是,常量只能是布尔型、数字(整数、浮点数以及复数)、字符串。其语法与使用如下:
//语法
const 常量名 [类型]=常量值
//示例
const name string="liyuanjing"
const age int=22
在Go语言中,可以省略类型说明符"[类型]"。因为编译器可以根据变量的值来判断其类型。
//显式声明
const Pi float32=3.1415926
//隐式声明
const Pi =3.1415926
需要注意的是,常量的值必须是能够在编译时被确定的,可以在其赋值表达式中涉及计算过程。但是所有用于计算的值,必须在编译期间就能获得。比如3/2就可以,但如果os.GetEnv(‘url’)调用方法,就不行。因为方法调用只有在运行时才能知道返回结果。
常量声明有时候还可以使用常量生成器iota初始化。iota用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式。
这里要提前说一下,在Go语言中,是没有枚举类型的。我们通常就是通过iota进行枚举类型的实现。比如,现在我们需要定义东南西北4个枚举类型,那么可以直接这样实现:
type Direction int
const(
North Direction=iota
East
South
West
)
如上面代码所示,默认North就是0,之后每一个值的常量自动被加1。
运算符
顾名思义,与其他语言一样都是计算。下面,我们随便举个例子就行:
var a,b,c int=1,2,3
d :=a+b*c
通过上面代码,我们可以很容易的计算出来,d等于7。
以上是关于go相当详细的基础语法的主要内容,如果未能解决你的问题,请参考以下文章