一、语法结构

  • Go语言主要有四种类型的声明语句:var, const, type 和 func, 分别对应变量, 常量, 类型和函数实体对象的声明
// 当前程序的包名(一个可执行程序只有一个 main 包)
//一般建议package的名称和目录名保持一致
package main

// 导入其它包
// 缺少或未使用的包,程序都无法编译通过
import "fmt"

// 通过 const 关键字来进行常量的定义
const number1 = 10

// 通过 var 关键字来声明变量
var number2 = 20

// 数组
var number3 = [5]int{1, 3, 5, 7, 9}

// 集合
var number4 = map[string]int{
    "Age1": 18,
    "Age2": 19,
    "Age2": 20,
}

// 一般类型声明
type number5 int

// 结构声明
type number6 struct{}

// 接口声明
type number7 interface{}

// 通过 func 关键字来进行函数的声明
// 只有 package 名称为 main 的包才可以包含 main 函数
func main() {
    fmt.Println("Hello World")
}

二、变量、常量

2.1命名规则

  • 名字必须以一个字母或下划线开头, 后面可以跟任意数量的字母, 数字或下划线
  • 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语言有大约30多个预定义的名字, 比如int和true等, 主要对应内建的常量类型和函数
  1. 常量: true false iota nil
  2. 类型: int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr
    float32 float64 complex128 complex64 bool byte rune string error
  3. 函数: make len cap new append copy close delete complex real imag panic recover
  4. 这些内部预先定义的名字并不是关键字, 你可以在定义中重新使用它们, 但是要注意避免语义混乱
  • 根据首字母的大小写来确定可以访问的权限; 首字母大写, 可以被其他的包访问; 首字母小写, 则只能在本包中使用

2.2变量

  • var 变量名字 类型 = 表达式

  • 已声明但未使用的变量会在编译阶段报错

    [root@devlop devlop]# vim variable.go

    package main
    
    import "fmt"
    
    func main() {
    
    var a int = 1
    fmt.Println(a)
    
    //var可以声明一个或多个变量
    var b, c string = "a", "b"
    fmt.Println(b, c)
    
    //声明为没有相应初始化的变量是零值的(int的零值是0, string的零值是空)
    var d int
    fmt.Println(d)
    
    //Go将推断初始化变量的类型
    //(:=)简短变量声明一般用于局部变量的声明和初始化,var往往是用在需要先指定变量类型稍后再赋值的
    //不过它有一个限制,那就是它只能用在函数内部;在函数外部使用则会无法编译通过,所以一般用var方式来定义全局变量
    e := true
    fmt.Println(e)
    
    //_(下划线)是个特殊的变量名,任何赋予它的值都会被丢弃
    _, f := 7, 8
    fmt.Println(f)
    }

    [root@devlop devlop]# go run variable.go

    1
    a b
    0
    true
    8

    2.3常量

// Go支持字符, 字符串, 布尔值和数值的常量
package main

import "fmt"

//用 const 关键字定义常量
const a string = "A"

func main() {

    fmt.Println(a)

    //const 可以定义一个或多个常量
    const b, c = 1, 3
    fmt.Println(b, c)

    //表达式里可以有常量, 但不能有变量
    const d = 4 - b
    fmt.Println(d)

}

[root@devlop devlop]# go run const.go

A
1 3
3

2.4常量计数器iota

  • iota是常量的计数器, 从0开始, 组中每定义1个常量自动递增1
  • 每遇到一个const关键字, iota就会重置为0
package main

import "fmt"

const (
  GB int = 1 << (iota * 10)  //GB=1,iota=0,向左移0位
  MB int = 1 << (iota * 10) //MB=1=00000001(二进制),iota=1,(1*10)=10,左移10位,再转换十进制
  KB int = 1 << (iota * 10) //KB=1=00000001(二进制),iota=2,(2*10)=20,左移20位,再转换十进制
)

const (
    a int = iota
    b
)

func main() {

    fmt.Println(GB, MB, KB)
    fmt.Println(a, b)

}
1 1024 1048576
0 1

2.5字符串格式化

Go语言中的单引号、双引号、反引号

一个Go语言字符串是一个任意字节的常量序列。Go语言的字符串类型在本质上就与其他语言的字符串类型不同。Java的String、C++的std::string以及python3的str类型都只是定宽字符序列,而 Go语言的字符串是一个用UTF-8编码的变宽字符序列,它的每一个字符都用一个或多个字节表示

Go语言中的字符串字面量使用 双引号 或 反引号 来创建

Println和Printf的区别

Println能输出字符串,也能输出一个变量

a:=10
fmt.Println(a)            //right
fmt.Println("hello")      //right

Printf只能输出格式化的字符串,不能输出一个变量

a:=10
fmt.Printf(a)            //wrong,报错如下
fmt.Printf("a=%d",a)     //right

Go基础语法

fmt包Printf方法详解

Go语言的标准输出流在打印到屏幕时有些参数跟别的语言(比如C#和Java)不同,下面是我整理的一些常用的格式化输入操作。

General
  • %v 以默认的方式打印变量的值
  • %T 打印变量的类型
Integer
  • %+d 带符号的整型,fmt.Printf("%+d", 255)输出+255
  • %q 打印单引号
  • %o 不带零的八进制
  • %#o 带零的八进制
  • %x 小写的十六进制
  • %X 大写的十六进制
  • %#x 带0x的十六进制
  • %U 打印Unicode字符
  • %#U 打印带字符的Unicode
  • %b 打印整型的二进制
Integer width
  • %5d 表示该整型最大长度是5,下面这段代码

    fmt.Printf("|%5d|", 1)
    fmt.Printf("|%5d|", 1234567)

输出结果如下:

|    1|
|1234567|   
  • %-5d则相反,打印结果会自动左对齐
  • %05d会在数字前面补零。
Float
  • %f (=%.6f) 6位小数点
  • %e (=%.6e) 6位小数点(科学计数法)
  • %g 用最少的数字来表示
  • %.3g 最多3位数字来表示
  • %.3f 最多3位小数来表示
String
  • %s 正常输出字符串
  • %q 字符串带双引号,字符串中的引号带转义符
  • %#q 字符串带反引号,如果字符串内有反引号,就用双引号代替
  • %x 将字符串转换为小写的16进制格式
  • %X 将字符串转换为大写的16进制格式
  • % x 带空格的16进制格式
String Width (以5做例子)
  • %5s 最小宽度为5
  • %-5s 最小宽度为5(左对齐)
  • %.5s 最大宽度为5
  • %5.7s 最小宽度为5,最大宽度为7
  • %-5.7s 最小宽度为5,最大宽度为7(左对齐)
  • %5.3s 如果宽度大于3,则截断
  • %05s 如果宽度小于5,就会在字符串前面补零
Struct
  • %v 正常打印。比如:{sam {12345 67890}}
  • %+v 带字段名称。比如:{name:sam phone:{mobile:12345 office:67890}
  • %#v 用Go的语法打印。
    比如main.People{name:”sam”, phone:main.Phone{mobile:”12345”, office:”67890”}}
Boolean
  • %t 打印true或false
Pointer
  • %p 带0x的指针
  • %#p 不带0x的指针
参考

fmt 包

// Print 将参数列表 a 中的各个参数转换为字符串并写入到标准输出中。
// 非字符串参数之间会添加空格,返回写入的字节数。
func Print(a ...interface{}) (n int, err error)

// Println 功能类似 Print,只不过最后会添加一个换行符。
// 所有参数之间会添加空格,返回写入的字节数。
func Println(a ...interface{}) (n int, err error)

// Printf 将参数列表 a 填写到格式字符串 format 的占位符中。
// 填写后的结果写入到标准输出中,返回写入的字节数。
func Printf(format string, a ...interface{}) (n int, err error)

------------------------------

// 功能同上面三个函数,只不过将转换结果写入到 w 中。
func Fprint(w io.Writer, a ...interface{}) (n int, err error)
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)

------------------------------

// 功能同上面三个函数,只不过将转换结果以字符串形式返回。
func Sprint(a ...interface{}) string
func Sprintln(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string

------------------------------

// 功能同 Sprintf,只不过结果字符串被包装成了 error 类型。
func Errorf(format string, a ...interface{}) error