Go基础学习

Go简明教程

语言结构
  • Go语言的基础组成有以下几个部分:

  1. 包声明

  1. 引入包

  1. 函数

  1. 变量

  1. 语句&表达式

  1. 注释

  • 以Go的Hello World为例,了解Go应用程序的各个部分

package main
//package main 定义了包名,必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包
import "fmt"
//import "fmt" 告诉Go编译器这个程序需要使用 fmt 包,fmt 包实现了格式化IO的函数
func main(){
/**
 *func main()函数开始执行的函数,main函数是每一个可执行程序必须包含的
 *需要注意的是 { 不能单独放在一行,否则代码在运行时会产生错误
*/
    fmt.Println("Hello World!")
    //一行为一个语句,结尾不需要';'
}
  • 执行Go程序

#若我们将上述代码保存为hello.go,可以在命令行中输入下列命令运行
$ go run hello.go
Hello World!
#还可以使用go build来生成二进制文件
$ ls
hello.go
$ go build hello.go
$ ls
hello hello.go
$ ./hello
Hello World!
基础语法
  • 行分隔符:一行代表一个语句结束

  • 注释:单行注释 // 多行注释 /* 注释内容*/

  • 标识符:用来命名变量、类型等程序的实体;由字母数字和下划线组成,第一个字符必须是字母或者下划线

  • 字符串连接:Go语言字符串可以通过 + 实现

  • 关键字

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

  • 36 个预定义标识符

append

bool

byte

cap

close

complex

complex64

complex128

uint16

copy

false

float32

float64

imag

int

int8

int16

uint32

int32

int64

iota

len

make

new

nil

panic

uint64

print

println

real

recover

string

true

uint

uint8

uintptr

数据类型
  • 布尔型:var b bool = true

  • 数字类型

  1. uint8 无符号8位整型(0 - 255)

  1. uint16

  1. uint32

  1. uint64

  1. int8 有符号8位整型(-128 - 127)

  1. int6

  1. int32

  1. int64

  1. float32

  1. float64

  1. complex64 (32位实数和虚数)

  1. complex128

  1. byte (类似uint8)

  1. rune (int32)

  1. uint (32位或64位)

  1. int (与uint一样大小)

  1. uintptr (无符号整型,用于存放一个指针)

变量
  • 变量名由字母、数字、下划线组成,首个字符不能为数字

  • 声明变量的一般形式是使用 var 关键字,可以一次声明多个变量

  • 变量声明:在相同的代码块中,我们不可以再次对于相同名称的变量使用初始化声明

  1. 指定变量类型,如果没有初始化,则变量默认为0,布尔值则为false,字符串则为空

var v_name v_type
v_name = value
  1. 根据值自行判断变量类型

var v_name = value
  1. 使用 := 声明变量

val := 1
//相当于
var val int
val = 1
  1. 多变量声明

var vname1, vname2 = v1, v2
//或
vname1, vname2 := v1, v2
//因式分解关键词的写法一般用于声明全局变量
var (
	vname1 v_type1
	vname2 v_type2
)
常量
  • 常量是一个简单值得标识符,在程序运行时,不会被修改的量

  • 常量的数据类型只能是布尔型、数字型、字符串型

const vname [type] = value
//显式类型定义
const b string = "abc"
//隐式类型定义
const b = "abc"
//常量还可以用作枚举
const (
	Female = 1
	Male = 2
)
  • iota 特殊常量,可以认为是一个可以被编译器修改的常量

  • iota 在 const 关键词出现时将被重置为0,const 中每新增一行常量声明将使 iota 计数一次

const (
	a = iota
	b = iota
	c = iota
)
//也可以简写为
const (
	a = iota
	b
	c
)
//a = 0, b = 1, c = 2
//一个有趣的例子
const (
    i=1<<iota
    j=3<<iota
    k
    l
)
//ota 表示从 0 开始自动加 1,所以 i=1<<0, j=3<<1(<< 表示左移的意思),即:i=1, j=6,这没问题,关键在 k 和 l,从输出结果看 k=3<<2,l=3<<3。
//注:value<<n==value*(2^n)。
运算符
  • 算术运算符、关系运算符、逻辑运算符、赋值运算符与 C 一样

  • 位运算符:对整数在内存中的二进制位进行操作

运算符

描述:假定 A = 60; B = 13; 其二进制数转换为 A = 0011 1100 B = 0000 1101

实例

&

按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。

(A & B) 结果为 12, 二进制为 0000 1100

|

按位或运算符"|"是双目运算符。 其功能是参与运算的两数各对应的二进位相或

(A | B) 结果为 61, 二进制为 0011 1101

^

按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。

(A ^ B) 结果为 49, 二进制为 0011 0001

<<

左移运算符"<<"是双目运算符。左移n位就是乘以2的n次方。 其功能把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。

A << 2 结果为 240 ,二进制为 1111 0000

>>

右移运算符">>"是双目运算符。右移n位就是除以2的n次方。 其功能是把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。

A >> 2 结果为 15 ,二进制为 0000 1111

  • 运算符优先级

优先级

运算符

5

* / % << >> & &^

4

+ - | ^

3

== != < <= > >=

2

&&

1

||

条件语句
  • if 语句

/**
 * if 布尔表达式 {
 *	执行语句
 *}
*/
if a < 20 {
    fmt.Println("a 小于 20\n")
}
  • switch 语句

/**
switch var1 {
	case value1 :
    	...
	case value2 :
		...
	default :
		...
}
*/
switch marks {
      case 90: grade = "A"
      case 80: grade = "B"
      case 50,60,70 : grade = "C"
      default: grade = "D"  
}
//不同的 case 之间不使用 break 分隔,默认只会执行一个 case。如果想要执行多个 case,需要使用 fallthrough 关键字,也可用 break 终止。
switch {
    case false:
            fmt.Println("1、case 条件语句为 false")
            fallthrough
    case true:
            fmt.Println("2、case 条件语句为 true")
            fallthrough
    case false:
            fmt.Println("3、case 条件语句为 false")
            fallthrough
    case true:
            fmt.Println("4、case 条件语句为 true")
    case false:
            fmt.Println("5、case 条件语句为 false")
            fallthrough
    default:
            fmt.Println("6、默认 case")
}
/**
 *执行结果为:
 *2、case 条件语句为 true
 *3、case 条件语句为 false
 *4、case 条件语句为 true
*/
//switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型
switch i := x.(type) {
      case nil:  
         fmt.Printf(" x 的类型 :%T",i)                
      case int:  
         fmt.Printf("x 是 int 型")                      
      case float64:
         fmt.Printf("x 是 float64 型")          
      case func(int) float64:
         fmt.Printf("x 是 func(int) 型")                      
      case bool, string:
         fmt.Printf("x 是 bool 或 string 型" )      
      default:
         fmt.Printf("未知型")    
}
//执行结果为:x 的类型 :<nil>
  • select 语句:select 是 Go 中的一个控制结构,类似于 switch 语句。select 语句只能用于通道操作,每个 case 必须是一个通道操作,要么是发送要么是接收。select 语句会监听所有指定的通道上的操作,一旦其中一个通道准备好就会执行相应的代码块。如果多个通道都准备好,那么 select 语句会随机选择一个通道执行。如果所有通道都没有准备好,那么执行 default 块中的代码。

select {
  case <- channel1:
    // 执行的代码
  case value := <- channel2:
    // 执行的代码
  case channel3 <- value:
    // 执行的代码
    // 你可以定义任意数量的 case
  default:
    // 所有通道都没有准备好,执行的代码
}
// 如果任意某个通道可以进行,它就执行,其他被忽略。如果有多个 case 都可以运行,select 会随机公平地选出一个执行,其他不会执行。否则:如果有 default 子句,则执行该语句。如果没有 default 子句,select 将阻塞,直到某个通道可以运行;Go 不会重新对 channel 或值进行求值。
循环语句
  • for循环

sum := 0
for i := 0; i <= 10; i++ {
	sum += i
}
//无限循环
for {
    sum++
}

//for-each range 循环 这种格式的循环可以对字符串、数组、切片等进行迭代输出元素
numbers := [6]int{1, 2, 3, 5}
for i,x:= range numbers {
	fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
} 

//for 循环的 range 格式可以省略 key 和 value
map1 := make(map[int]float32)
map1[1] = 1.0
map1[2] = 2.0
map1[3] = 3.0
map1[4] = 4.0

// 读取 key 和 value
for key, value := range map1 {
	fmt.Printf("key is: %d - value is: %f\n", key, value)
}
// 读取 key
for key := range map1 {
	fmt.Printf("key is: %d\n", key)
}
// 读取 value
for _, value := range map1 {
	fmt.Printf("value is: %f\n", value)
}
  • goto 语句:Go 语言的 goto 语句可以无条件地转移到过程中指定的行

func main() {
   /* 定义局部变量 */
   var a int = 10
   /* 循环 */
   LOOP: for a < 20 {
      if a == 15 {
         /* 跳过迭代 */
         a = a + 1
         goto LOOP
      }
      fmt.Printf("a的值为 : %d\n", a)
      a++    
   } 
函数
  • Go 语言最少有个 main() 函数。

//函数定义格式
func function_name( [parameter list] ) [return_types] {
   函数体
}
/**
 * func:函数由 func 开始声明
 * function_name:函数名称,参数列表和返回值类型构成了函数签名。
 * parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参  数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
 * return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
 * 函数体:函数定义的代码集合
*/
  • 函数可以返回多个值

func swap(x, y string) (string, string) {
   return y, x
}

func main() {
   a, b := swap("Google", "Runoob")
   fmt.Println(a, b)
}
数组
/* 数组声明 */
var variable_name [SIZE] variable_type
var balance [10] float32
/* 数组初始化 */
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
//或
balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
/* 如果数组长度不确定,可以使用 ... 代替数组的长度,编译器会根据元素个数自行推断数组的长度 */
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
/* 如果设置了数组的长度,我们还可以通过指定下标来初始化元素 */
/* 如:将索引为 1 和 3 的元素初始化 */
balance := [5]float32{1:2.0,3:7.0}
指针
  • 一个指针变量指向了一个值的内存地址,类似于变量和常量,在使用指针前你需要声明指针

/* var var_name *var-type */
var ip *int        /* 指向整型 */
var fp *float32    /* 指向浮点型 */
  • 如何使用指针

func main() {
   var a int= 20   /* 声明实际变量 */
   var ip *int     /* 声明指针变量 */
   ip = &a  /* 指针变量的存储地址 */
   fmt.Printf("a 变量的地址是: %x\n", &a  )
   /* 指针变量的存储地址 */
   fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
   /* 使用指针访问值 */
   fmt.Printf("*ip 变量的值: %d\n", *ip )
}
/**
 a 变量的地址是: 20818a220
 ip 变量储存的指针地址: 20818a220
 *ip 变量的值: 20
*/
结构体
/**
定义
type struct_variable_type struct {
   member definition
   member definition
   ...
   member definition
}
*/
type Books struct {
   title string
   author string
   subject string
   book_id int
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值