zeromax 发表于 2018-9-20 08:12:20

GoLang之基础

GoLang之基础
  Go是一种并发的、带垃圾回收的、快速编译的语言。
  一个例子:
  

//当前程序的包名  
package main
  

  

//导入其它的包  
import (
  

"flag"  
"fmt"
  
"os"
  
)
  

  
//常量定义
  
const PI = 3.14
  

  
//全局变量的声明与赋值
  
var name = "go"
  

  
//一般类型的声明
  
type intType int
  

  
//结构声明
  
type newType struct {
  
}
  

  
//接口声明
  
type newInterface interface {
  
}
  

  
//main函数,程序的入口
  
func main() {
  
fmt.Println(os.Args)
  
flag.Parse()
  
fmt.Println(flag.Args())
  
}
  

  说明:
  1、每个go源代码文件的开头都是一个package声明,表示该go代码所属的包;包是go语言中最基本的分发单位,也是工程管理中依赖关系的体现。要生成go可执行程序,必须建立一个名为main的package,并且在该package中包含一个叫main()的函数;
  2、Go语言的main()函数不能带参数,也不能定义返回值,传入的命令行参数在os.Args变量中保存;
  3、在包声明之后,是一系列的import语句,用于导入改程序所依赖的包,但不能导入在源代码文件中没有用到的包,否则Go编译器会报错;
  4、Go语言中,语句不用以分号结束;
  编译、运行:
  

go run test.go  

  使用这个命令,会将编译、链接和运行3个步骤合并为一步,运行完成后在当前目录下看不到任何中间文件和最终的可执行文件。
  如果只要生成编译结果,而不自动运行,可以使用:
  

go build test.go  


变量
  变量声明语句:
  

var 变量名 变量类型  

  例子:
  

var v1 int              
var v2 string           // 字符串
  
var v3 [
10]int               // 数组  
var v4 []
int                  // 数组切片  
var v5 struct {         // 接口
  
f
int  
}
  
var v6
*int                  // 指针  
var v7 map
int      // map,key为string类型,value为int类型  
var v8 func(a
int) int     

  可以使用一个var关键字同时声明多个变量:
  

var (  
v1
int  
v2 string
  
)
  

  如果在声明变量的同时还进行了初始化,则var关键字可以省略,并且Go编译器可以从初始化表达式的右值推导出该变量应该声明为哪种类型,这有点类似于动态类型,但Go实际上是强类型的语言(静态类型语言)。
  如下所示三种用法的效果是一样的:
  

var v1 int = 10  
v2
int = 10    // 编译器自动推导出v2的类型  
v3 :
= 10      // 编译器自动推导出v3的类型  

  说明:
  ":="用于明确表达同时进行变量声明和初始化工作,但要注意出现在:=左侧的变量不应该是已经被声明过的,否则会导致编译器报错,如下:
  

var i int  
i :
= 2     //error  


常量
  在Go语言中,常量是指编译期间就已知且不可改变的值。

1、字面常量
  

-12       // 整型常量  
3.14      // 浮点型常量
  
3.2+12i    // 复数类型的常量
  
true      // 布尔型常量
  
"foo"     // 字符串常量
  

  在C语言中,常量通常有类型,比如-12在C语言中会认为是一个int类型,如果要指定它为long类型,需要写成-12L。
  在Go语言中,字面常量没有类型,只要这个常量在相应类型的值域范围内,就可以作为该类型的常量,比如上面的常量-12,可以赋值给int、uint、int32、int64、float32、float64、complex64、complex128等类型的变量。

2、const常量
  通过const常量,可以给字面常量指定一个友好的名字:
  

const Pi float64 = 3.1415  
const zero
= 0.0  //无类型浮点常量  
cosnt (
  
size int64
= 1024  
eof
= -1    //无类型整型常量  
)
  
const u,v float32
= 0, 3  
const a,b,c
= 3,4,"foo"  const mask = 1
}  
  delete(personDB, "1")        // 删除一个键
  
}
  

  遍历map的例子:
  

m1 := mapint{"one": 1, "two": 2, "three": 3}  
fmt.Println(m1)
  

  
for key, val :
= range m1{  
fmt.Printf(
"%s => %d \n", key, val)  
}
  

  注意:range支持对 string, array, slice, map, buffered chan的遍历;


9、结构体
  定义一个struct:
  

type Rect struct {  
x, y float64

  
width,>  
}
  

  初始化的几种方式:
  

rect1 := new(Rect)  
rect2 :
= &Rect{}  
rect3 :
= &Rect{0, 0, 100, 200}  
rect4 :
= &Rect{width:100,>  

  在Go语言中,未进行显式初始化的变量都会被初始化为该类型的零值,例如bool类型的零值为false,int类型的零值为0,string类型的零值为空字符串。

10、指针
  Go支持指针,例如:
  

var i int = 1  
var pInt
*int = &i  

  

//输出:i=1   pInt=0xf8400371b0       *pInt=1  
fmt.Printf(
"i=%d\tpInt=%p\t*pInt=%d\n", i, pInt, *pInt)  

  

*pInt = 2  
//输出:i=2   pInt=0xf8400371b0       *pInt=2
  
fmt.Printf("i=%d\tpInt=%p\t*pInt=%d\n", i, pInt, *pInt)
  

  
i = 3
  
//输出:i=3   pInt=0xf8400371b0       *pInt=3
  
fmt.Printf("i=%d\tpInt=%p\t*pInt=%d\n", i, pInt, *pInt)
  


package

Go程序是通过package来组织的:

[*]一个可执行程序有且仅有一个main包;
[*]只有package名称为main的包可以包含main函数;
[*]每个package都可以定义自己的init()函数,每个包被导入时,会执行其init()函数;
[*]import导入包时,是在$GOPATH变量定义的路径里面搜索;
[*]通过import关键字来导入其它非main包,有两种方式:

[*]  

import "flag"  
import
"fmt"  
import
"os"  

  

import (  

"flag"  
"fmt"
  
"os"
  
)
  



[*]导入包之后,使用.来对包中的函数进行调用;
[*]导入的包可以重命名,例如 import alias "PackageName",然后使用.来对包中的函数进行调用;
[*]将包名重命名为 ".",可以省略调用,例如 import . "PackageName",然后可以直接使用来对包中的函数进行调用;
[*]import _ "packageName" 操作不直接使用包里的函数,而是调用了该包的init函数;
[*]使用大小写来决定该常量、变量、类型、接口、结构或函数是否可以被外部包所调用——函数名首字母小写即为private,函数名首字母大写即为public;

内存分配
  Go具有两个分配内存的机制,分别是内建函数new()和make()。
  new 是一个分配内存的内建函数,new(T)为一个类型为T的新对象分配了值为零的存储空间并返回其地址,也就是一个类型为*T的值。用Go的术语来说,就是它返回了一个指向新分配的类型为T的零值的指针。
  make(T, args)仅用于创建slice、map和chan,并返回类型T(不是*T)的一个被初始化了的(不是零)实例。这三种类型实质上是对在使用前必须进行初始化的数据结构的引用:
  

slice := make([] type, len, cap)  
map :
= make(map value_type)  
chan :
= make(chan type, len)  

  以下示例说明了new和make的不同:
  

var p *[]int = new([]int)     // 为切片结构分配内存,*p == nil  
var v[]
int = make([]int, 10) // 切片v现在是对一个新的有10个整数的数组的引用  

  
fmt.Println(
*p) // []  
fmt.Println(v)
//   




流程控制

1、选择语句
  

if 条件表达式 {  
...
  
} else if{
  
...
  
} else {
  ...
  }
  

  注意:


[*]条件表达式不需要使用括号();
[*]条件语句体必须使用花括号,且"{"必须与 if 或者 else处于同一行;
[*]在if 和条件表达式之间,可以添加变量初始化语句,使用";"间隔;
[*]在有返回值的函数中,不允许将最终的return语句包含在if...else...结构中;
  switch语句:
  

switch i {        // 左花括号"{"必须与switch处于同一行  

case 0:  
fmt.Printf(
"0")  

case 1:  
fmt.Printf(
"0")  

case 2:  
fallthrough
  

case 3:  
fmt.Printf(
"3")  

case 4,5,6:  
fmt.Printf(
"multi")  
default:
  
fmt.Printf(
"default")  
}
  



[*]i=0时,输出0;
[*]i=1时,输出1;
[*]i=2时,输出3,fallthrough关键字表示继续执行下一个case;
[*]i=3时,输出3;
[*]i=4/5/6时,输出"multi",单个case后面可以出现多个结果项;
[*]i=其它任意值时,输出"default"。
  注意:


[*]Go语言不需要用break来退出一个case,只有在case中添加fallthrough关键字,才会继续执行紧跟的下一个case;
[*]条件表达式不限制为常量或者整数,条件表达式甚至也可以没有,例如:
  

Num := 8  
switch {
  

case 0
页: [1]
查看完整版本: GoLang之基础