Golang 语法结构与类型

2020-10-30  本文已影响0人  Mr_Michael

参考:the-way-to-go_ZH_CNbooks.studygolang.com

一、文件名、关键字与标识符

二、基本结构和要素

package main    //归属于main包

import "fmt"    // 导入 fmt 包(函数或其他元素)

//实现main包中的main函数,该函数会自动执行
func main() {
    fmt.Println("hello, world")  // fmt 包中的 Println 函数,可以将字符串输出到控制台,并在最后自动增加换行字符 \n
}

1.包的概念、导入与可见性

1)文件的归属与包的导入

2)可见性规则

3)包的分级声明和初始化

2.注释

3.打印

Go中的fmt几种输出的区别和格式化方式

fmt包有printf与println两个打印函数

4.变量、常量和类型

Go语言变量和常量的声明方式与C和C++语言明显不同, Go语言引入了关键字var,而类型信息放在变量或常量名之后。

1)变量

2)常量

3)类型

4)自定义类型

使用关键字type自定义类型

//自定义类型
type IZ int
var a IZ = 5

//定义多类型,使用因式分解关键字的方式
type (
   IZ int
   FZ float64
   STR string
)

5)类型转换

//int与float转换
var a float32 = 1234.12345678
b := int64(a)
c := float32(a)
d := float64(a)
e := float64(c)

// []byte转int(16进制转10进制)
import "fmt"
import "encoding/binary"
var a []byte = []byte{0, 1, 2, 3}  
binary.BigEndian.Uint32(a)      //0x00010203 ==> 66051
binary.LittleEndian.Uint32(a) //0x03020100 ==> 50462976

b  : = []byte{0x00, 0x00, 0x03, 0xe8}  
b_buf  : =  bytes .NewBuffer(b)  
var x int32  
binary.Read(b_buf, binary.BigEndian, &x)  
fmt.Println(x)  

b := []byte{0xe8, 0x03, 0xd0, 0x07}
x1 := binary.LittleEndian.Uint32(b[0:])

// int 转 []byte
x  =  1000  
b_buf  :=  bytes .NewBuffer([]byte{})  
binary.Write(b_buf, binary.BigEndian, x)  
fmt.Println(b_buf.Bytes())  

// float32 转uint32
math.Float32bits(f float32) uint32

// uint32 转 float32
Float32frombits(b uint32) float32

//uint32 转 []byte
func EncodeUint32(v uint32) []uint8 {
    b := make([]uint8, 4)
    binary.LittleEndian.PutUint32(b, v)
    return b
}

// string 转 []byte
var str string = "test"
var data []byte = []byte(str)

// []byte 转 string
var data [10]byte 
var str string = string(data[:])

// []byte -> String  (byte转ascii)
data1 := []byte{0x31, 0x32, 0x33, 0x34}
data2 := []byte("Hello")
str1 := string(data1)  //"1234"
str2 := string(data2)  //"Hello"
// []byte -> String  (byte转hex)
import "encoding/hex"
hexstr := hex.EncodeToString(data1)     //"31323334"
// String -> []byte (hex转byte)
tmp, _ := hex.DecodeString(hexstr)  //[49 50 51 52]


//===strconv包实现基本数据类型的字符串表示形式之间的转换===
import "strconv"
//数值转换
    //int转string
    strconv.Itoa(i int) string
    //string转int
    strconv.Atoi(s string) (i int, err error)
//将字符串转换为值
    //string转bool
    b, err := strconv.ParseBool("true")
    //string转float64
    f, err := strconv.ParseFloat("3.1415", 64)
    //string转int64,10进制表示
    i, err := strconv.ParseInt("-42", 10, 64)
    //string转uint64
    u, err := strconv.ParseUint("42", 10, 64)
//将值转换为字符串
    //bool转string
    s := strconv.FormatBool(true)
    //float64转string 64
    s := strconv.FormatFloat(3.1415, 'E', -1, 64)
    //int64转string,以10进制显示
    s := strconv.FormatInt(-42, 10)
    //uint64转string,以10进制显示
    s := strconv.FormatUint(42, 10)

5.运算符

6.Go 程序的一般结构示例

package main  //被 main 包引用,是一个可独立执行的程序

import (
   "fmt"
)

const c = "C"

var v int = 5

type T struct{}

//每个源文件都只能包含一个 init 函数, 执行优先级比 main 函数高
func init() { // initialization of package
}

func main() {
   var a int
   Func1()
   // ...
   fmt.Println(a)
}

func (t T) Method1() {
   //...
}

func Func1() { // exported function Func1
   //...
}

Go 程序的执行顺序:

  1. 按顺序导入所有被 main 包引用的其它包,然后在每个包中执行如下流程:
  2. 如果该包又导入了其它的包,则从第一步开始递归执行,但是每个包只会被导入一次。
  3. 然后以相反的顺序在每个包中初始化常量和变量,如果该包含有 init 函数的话,则调用该函数。
  4. 在完成这一切之后,main 也执行同样的过程,最后调用 main 函数开始执行程序。

三、控制结构

1.if-else

if condition1 {
    // do something 
} else if condition2 {
    // do something else    
} else {
    // catch-all or default
}

//示例
func main() {
    var first int = 10
    var cond int

    if first <= 0 {
        fmt.Printf("first is less than or equal to 0\n")
    } else if first > 0 && first < 5 {
        fmt.Printf("first is between 0 and 5\n")
    } else {
        fmt.Printf("first is 5 or greater\n")
    }
    if cond = 5; cond > 10 {
        fmt.Printf("cond is greater than 10\n")
    } else {
        fmt.Printf("cond is not greater than 10\n")
    }
}

2.switch

// 方式1
switch var1 {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}

//示例
func main() {
    var num1 int = 100

    switch num1 {
    case 98, 99:
        fmt.Println("It's equal to 98")
    case 100: 
        fmt.Println("It's equal to 100")
    default:
        fmt.Println("It's not equal to 98 or 100")
    }
}

//方式2
switch {
    case condition1:
        ...
    case condition2:
        ...
    default:
        ...
}

//示例
func main() {
    var num1 int = 7

    switch {
        case num1 < 0:
            fmt.Println("Number is negative")
        case num1 > 0 && num1 < 10:
            fmt.Println("Number is between 0 and 10")
        default:
            fmt.Println("Number is 10 or greater")
    }
}

3.for

// 格式
for 初始化语句; 条件语句; 修饰语句 {
        // do something 
}

//示例
func main() {
    for i := 0; i < 5; i++ {
        fmt.Printf("This is the %d iteration\n", i)
    }
}

//for-range 结构
for i, char := range str {
    ...
}
//示例
func main() {
    str := "Go is a beautiful language!"
    fmt.Printf("The length of str is: %d\n", len(str))
    for pos, char := range str {
        fmt.Printf("Character on position %d is: %c \n", pos, char)
    }
}

四、函数

Go 里面有三种类型的函数:

1.普通函数

//普通函数格式
    // 入口参数:parameter_list 的形式为 (param1 type1, param2 type2, …)
    // 回调参数: return_value_list 的形式为 (ret1 type1, ret2 type2, …)
func functionName(parameter_list) (return_value_list) {
   …
}

//示例
func Atoi(s string) (i int, err error)
//调用
num, err := Atoi("12")

//自定义一个函数类型别名
type name func(type1,type2) type3
//示例
type binOp func(int, int) int
add := binOp

2.匿名函数

func(parameter_list) (return_value_list) {...}
//示例
fplus := func(x, y int) int { return x + y }
num := fpus(1,2)

3.方法

什么是面向对象编程思想?

面向对象编程(OOP)把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。把程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,程序的执行就是一系列消息在各个对象之间传递。

五、数组与切片

声明数组的格式是: var identifier [n]type

把一个大数组传递给函数会消耗很多内存。有两种方法可以避免这种现象:

切片(slice)是对数组一个连续片段的引用,这个片段可以是整个数组,或者是由起始和终止索引标识的一些项的子集。多个切片如果表示同一个数组的片段,它们可以共享数据;因此一个切片和相关数组的其他切片是共享存储的。

1.new() 和 make() 的区别

2.For-range 结构

//这种构建方法可以应用于字符串(本质是字节数组)、数组和切片
for ix, value := range slice1 {
    ...
}

3.切片的复制与追加

如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。

//复制切片
sl_from := []int{1, 2, 3}
sl_to := make([]int, 10)
n := copy(sl_to, sl_from)

//追加切片
sl3 := []int{1, 2, 3}
sl3 = append(sl3, 4, 5, 6)

append 方法将 0 个或多个具有相同类型 s 的元素追加到切片后面并且返回新的切片

如果 s 的容量不足以存储新增元素,append 会分配新的切片来保证已有切片元素和新增元素的存储。

六、Map

map 是一种特殊的数据结构:一种元素对(pair)的无序集合,pair 的一个元素是 key,对应的另一个元素是 value,所以这个结构也称为关联数组或字典。

1.概念

1)map的声明及初始化

var map1 map[keytype]valuetype

var mapLit map[string]int
mapLit = map[string]int{"one": 1, "two": 2}

//通过make函数初始化
var map1 = make(map[keytype]valuetype)

五、包(Package)

1.标准库

fmtos 等这样具有常用功能的内置包在 Go 语言中有 150 个以上。

unsafe: 包含了一些打破 Go 语言“类型安全”的命令,一般的程序中不会被使用,可用在 C/C++ 程序的调用中。

syscall-os-os/exec:

Golang标准库文档

2.第三方包

golang 标准库及第三方库文档

上一篇 下一篇

猜你喜欢

热点阅读