手记

Go 语言基础入门总结分析

Go 语言基础入门总结分析
语言结构
  • 包声明
  • 包引入
  • 函数
  • 变量
  • 语句&表达式
  • 注释
/* 定义包名 */
package main
/* 告诉go,需要fmt(格式化I/O)包 */
import "fmt"
/* 入口函数 */
func main() {
   fmt.Println("Hello, World!")
}
//执行go
go run hello.go //Hello, World!
基础语法
  • Go标记(关键字,标识符,常量,字符串,符号)
  • 行分割符(Go自动每行加分号)
  • 注释,标识符,关键字,同JS
  • Go空格(变量声明必须用空格隔开)

    fruit = apple + banana

    数据类型

  • 布尔型:true,false
  • 数字型:int,float
  • 字符串型:UTF-8标识Unicode文本
  • 派生型
    • 指针型(Pointer)
    • 数组型
    • 结构化型(struct)
    • Channel类型
    • 函数类型
    • 切片类型
    • 接口类型(interface)
    • Map类型
语言变量
  • 变量声明

    //指定变量类型,默认赋值
    var v_name v_type
    //根据值自动判断类型
    var v_name = value
    //省略var,:=左侧变量必须是未声明的
    v_name := value
    var a int = 10
    var b = 10
    c := 10
  • 多变量声明
    
    var v1 , v2 , v3 type
    var v1 , v2 , v3 = a , b ,c
    v1 , v2 , v3 := a , b ,c
    //一般因式分解关键字的写法用于全局变量声明
    var (
    vname1 v_type1
    vname2 v_type2
    )
    ckage main

var x, y int
var ( // 这种因式分解关键字的写法一般用于声明全局变量
a int
b bool
)

var c, d int = 1, 2
var e, f = 123, "hello"

//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"

func main(){
g, h := 123, "hello"
println(x, y, a, b, c, d, e, f, g, h)
}

- 值类型( int、float、bool 和 string)和引用类型
- 常量

const indentifer [type] = vlaue

const c_name1, c_name2 = value1, value2
package main

import "fmt"

func main() {
const LENGTH int = 10
const WIDTH int = 5
var area int
const a, b, c = 1, false, "str" //多重赋值

area = LENGTH * WIDTH
fmt.Printf("面积为 : %d", area)
println()
println(a, b, c)
}

- iota : 特殊常量,可被编译器修改;可被用作枚举值

const (
a = iota
b = iotb
c = iotc
)
//same as
const (
a = iota
b
c
)

## 运算符及优先级同JS

- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 其他运算符

## 条件与循环(类JS)

if boolean_exp {
/ ... /
}
for a := 0; a < 10; a++ {
fmt.Printf("a 的值为: %d\n", a)
}

## 函数(至少一个main函数)

func function_name( [parameter list] ) [return_types] {
//...
}

package main

import "fmt"

func main() {
/ 定义局部变量 /
var a int = 100
var b int = 200
var ret int

/ 调用函数并返回最大值 /
ret = max(a, b)

fmt.Printf( "最大值是 : %d\n", ret )
}

/ 函数返回两个数的最大值 /
func max(num1, num2 int) int {
/ 定义局部变量 /
var result int

if (num1 > num2) {
result = num1
} else {
result = num2
}
return result
}

### 函数参数
- 值传递:函数调用时将实际参数复制一份到函数,二者相互独立
- 引用传递:函数调用时将实际参数的地址传递到函数,二者相互影响

### 函数用法
- 作为值
- 闭包
- 方法

## 变量作用域

### 三种变量类型

- 局部变量:在函数内定义
- 全局变量:在函数外定义
- 形参:函数定义中的变量

### 初始化局部和全局变量
``` int,float32 均为0;pointer为nil```

## 数组

### 声明

var variable_name [SIZE] variable_type
//examples
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

### 访问成员(同JS)

## 指针
> 旨在简单执行一些任务,变量是一种使用方便的占位符,用于内存地址引用
一个指针变量可以指向任何一个值的内存地址,使用指针前要声明

package main

import "fmt"

func main() {
var a int= 20 / 声明实际变量 /
var ip int / 1.声明指针变量 */

ip = &a / 2. 为指针变量赋值,指针变量的存储地址 /

fmt.Printf("a 变量的地址是: %x\n", &a )

/ 指针变量的存储地址 /
fmt.Printf("ip 变量储存的指针地址: %x\n", ip )

/ 3. 访问指针变量中指向地址的值,使用指针访问值 /
fmt.Printf("ip 变量的值: %d\n", ip )
}

- Go空指针:当一个指针被定义后没有分配到任何变量时,它的值为 nil。

## 结构体

> 数组可以存储同一类型的数据,但结构体中可以定义不同类型数据。结构体即一些列同或异类型
的数据构成的集合。

### 定义

type struct_variable_type struct {
member definition;
member definition;
...
member definition;
}
//旦定义了结构体类型,它就能用于变量的声明
variable_name := structure_variable_type {value1, value2...valuen}
//访问用.语法

## 切片(slice)

> 切片是对数组的抽象,Go提供了一种灵活强悍的内置类型切片

//定义切片
var identifier []type
//初始化
s :=[] int {1,2,3 }
//使用make()函数来创建切片:
slice1 := make([]type, len)

## Range
> 用于for循环中迭代数组(array)、切片(slice)、链表(channel)或集合(map)的元素

package main
import "fmt"
func main() {
//这是我们使用range去求一个slice的和。使用数组跟这个很类似
nums := []int{2, 3, 4}
sum := 0
for , num := range nums {
sum += num
}
fmt.Println("sum:", sum)
//在数组上使用range将传入index和值两个变量。上面那个例子我们不需要使用该元素的序号,所以我们使用空白符"
"省略了。有时侯我们确实需要知道它的索引。
for i, num := range nums {
if num == 3 {
fmt.Println("index:", i)
}
}
//range也可以用在map的键值对上。
kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs {
fmt.Printf("%s -> %s\n", k, v)
}
//range也可以用来枚举Unicode字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。
for i, c := range "go" {
fmt.Println(i, c)
}
}
//输出
sum: 9
index: 1
a -> apple
b -> banana
0 103
1 111

## Map集合

> 无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,
我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。

/ 声明变量,默认 map 是 nil /
var map_variable map[key_data_type]value_data_type

/ 使用 make 函数 /
map_variable = make(map[key_data_type]value_data_type)

## 递归函数

package main

import "fmt"

func Factorial(x int) (result int) {
if x == 0 {
result = 1;
} else {
result = x * Factorial(x - 1);
}
return;
}

func main() {
var i int = 15
fmt.Printf("%d 的阶乘是 %d\n", i, Factorial(i))
}

## 类型转换

type_name(expression)

package main

import "fmt"

func main() {
var sum int = 17
var count int = 5
var mean float32

mean = float32(sum)/float32(count)
fmt.Printf("mean 的值为: %f\n",mean)
}
// 3.400000

## 接口
> Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

/ 定义接口 /
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
}

/ 定义结构体 /
type struct_name struct {
/ variables /
}

/ 实现接口方法 /
func (struct_name_variable struct_name) method_name1() [return_type] {
/ 方法实现 /
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
/ 方法实现/
}

package main

import (
"fmt"
)

type Phone interface {
call()
}

type NokiaPhone struct {
}

func (nokiaPhone NokiaPhone) call() {
fmt.Println("I am Nokia, I can call you!")
}

type IPhone struct {
}

func (iPhone IPhone) call() {
fmt.Println("I am iPhone, I can call you!")
}

func main() {
var phone Phone

phone = new(NokiaPhone)
phone.call()

phone = new(IPhone)
phone.call()

}

## 错误处理

type error interface {
Error() string
}

7人推荐
随时随地看视频
慕课网APP