Golang

gaojy · · 1115 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang

安装:

http://studygolang.com/articles/1605

http://www.cnblogs.com/linuxprobe/p/5654380.html

参考:go语言编程

 变量

声明

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

指针的使用:

package main
import "fmt"
func main() {
   var a int= 20   /* 声明实际变量 */
   var ip *int        /* 声明指针变量 */
   ip = &a  /* 指针变量的存储地址   20818a220*/
   fmt.Printf("a 变量的地址是: %x\n", &a  )
   /* 指针变量的存储地址  20818a220*/
   fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
   /* 使用指针访问值  20 */
   fmt.Printf("*ip 变量的值: %d\n", *ip )

 

初始化

var v1 int = 10 // 正确的使用方式1
var v2 = 10 // 正确的使用方式2,编译器可以自动推导出v2的类型
v3 := 10 // 正确的使用方式3,编译器可以自动推导出v3的类型

(冒号和等号的组合:=),用于明确表达同时进行变量声明和初始化的工作 。

变量赋值

var  v10  int
v10  =  123

多重赋值:交换

i , j = j  ,i

 

常量  const

const Pi float64 = 3.14159265358979323846
const zero = 0.0 // 无类型浮点常量
const (
size int64 = 1024
eof = -1 // 无类型整型常量
)
const u, v float32 = 0, 3 // u = 0.0, v = 3.0,常量的多重赋值
const a, b, c = 3, 4, "foo"
 a = 3, b = 4, c = "foo", 无类型整型和字符串常量

枚举

大写字母的常量 包外可见

const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
numberOfDays // 这个常量没有导出
)

类型

 布尔类型: bool。
 整型: int8、 byte、 int16、 intuint、 uintptr等。
 浮点类型: float32、 float64
 复数类型: complex64、 complex128。
 字符串: string。
 字符类型: rune。
 错误类型: error。
此外, Go语言也支持以下这些复合类型:
 指针(pointer)
 数组(array)
 切片(slice)
 字典(map)
 通道(chan)
 结构体(struct)
 接口(interface

字符串:

字符串不能在初始化之后修改:

str := "Hello world" // 字符串也支持声明时进行初始化的做法
str[0] = 'X' // 编译错误

字符串遍历:

str := "Hello,世界"
n := len(str)
for i := 0; i < n; i++ {
ch := str[i] // 依据下标取字符串中的字符,类型为byte
fmt.Println(i, ch)
}

 

 

str := "Hello,世界"
for i, ch := range str {
fmt.Println(i, ch)//ch的类型为rune
}

字符类型

byte类型 == int8   用于表示UTF-8字符串单个字节的值

rune表示单个unicode字符

数组

数组声明

[32]byte 
[2*N] struct { x, y int32 } 
[1000]*float64 
[3][5]int 
[2][2][2]float64 

遍历:

for i := 0; i < len(array); i++ {
fmt.Println("Element", i, "of array is", array[i])
}

for i, v := range array {
fmt.Println("Array element[", i, "]=", v)
}

注意:go中数组是值类型,赋值或作为参数传递时会发生数据复制。

package main
import "fmt"
func modify(array [10]int) {
array[0] = 10 // 试图修改数组的第一个元素
fmt.Println("In modify(), array values:", array)
}
func main() {
array := [5]int{1,2,3,4,5} // 定义并初始化一个数组
modify(array) // 传递给一个函数,并试图在函数体内修改这个数组内容
fmt.Println("In main(), array values:", array)
}
该程序的执行结果为:
In modify(), array values: [10 2 3 4 5]
In main(), array values: [1 2 3 4 5]

数组切片

数组的长度定义后不能改变,同时又是值类型,每次传递都会数据复制,而数据切片可以管理数据。

基于数组创建

// 先定义一个数组
var myArray [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
// 基于数组创建一个数组切片
var mySlice []int = myArray[:5]
------------------------------------
var mySlice []int = myArray[:]    基于myArray所有元素创建数组切片
var mySlice [] int = myArray[:5]  基于myArray前5个元素创建数组切片
var mySlice [] int = myArray[5:] 基于myArray第5个后面的所有元素创建数组切片

直接创建

创建一个初始元素个数为5的数组切片,元素初始值为0:
mySlice1 := make([]int, 5)
创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间:
mySlice2 := make([]int, 5, 10)
直接创建并初始化包含5个元素的数组切片:
mySlice3 := []int{1, 2, 3, 4, 5}

cap()函数返回的是数组切片分配的空间大小,而len()函数返回的是数组切片中当前所存储的元素个数。数组切片支持Go语言内置的cap()函数和len()函数。

copy()内容复制
slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{5, 4, 3}
copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2
copy(slice1, slice2) // 只会复制slice23个元素到slice1的前3个位置

 map

// PersonInfo是一个包含个人详细信息的类型
type PersonInfo struct {
ID string
Name string
Address string
}
变量声明
var myMap  map[string]  PersonInfo
创建 
myMap = make(map[string] PersonInfo)
myMap = make(map[string] PersonInfo, 100)  指定存储能力
赋值
myMap["1234"] = PersonInfo{"1", "Jack", "Room 101,..."}
删除
delete(myMap, "1234")
查找
value, ok := myMap["1234"]
if ok { // 找到了
// 处理找到的value
}

 流程控制

if a < 5 {
return 0
} else {
return 1
}
关于条件语句,需要注意以下几点:
 条件语句不需要使用括号将条件包含起来();
 无论语句体内有几条语句,花括号{}都是必须存在的;
 左花括号{必须与if或者else处于同一行;
 在if之后,条件语句之前,可以添加变量初始化语句,使用;间隔;
 在有返回值的函数中,不允许将“最终的” return语句包含在if...else...结构中,否则会编译失败
switch i {
case 0:
fmt.Printf("0")
case 1:
fmt.Printf("1")
case 2:
fallthrough
case 3:
fmt.Printf("3")
case 4, 5, 6:
fmt.Printf("4, 5, 6")
default:
fmt.Printf("Default")
}
在使用switch结构时,我们需要注意以下几点:
 左花括号{必须与switch处于同一行;
 条件表达式不限制为常量或者整数;
 单个case中,可以出现多个结果选项;
 与C语言等规则相反, Go语言不需要用break来明确退出一个case;
 只有在case中明确添加fallthrough关键字,才会继续执行紧跟的下一个case;
 可以 不设定switch之 后的条 件表达式, 在此种情况 下,整个switch结构与 多个
if...else...的逻辑作用等同。

函数

func Add(a int, b int) (ret int, err error) {
  if a < 0 || b < 0 { // 假设这个函数只支持两个非负数字的加法
  err= errors.New("Should be non-negative numbers!")
  return
  }
  return a + b, nil // 支持多重返回值
}

函数调用  c := mymath.Add(1, 2)

注意:小写字母开头的函数只能本包可见,大写字母的函数才能被其他包使用。

 

不定参数

func myfunc(args ...int) {
for _, arg := range args {
fmt.Println(arg)
}
}

 

任意类型的不定参数:

func Printf(format string, args ...interface{}) {
// ...
}

多返回值

func (file *File) Read(b []byte) (n int, err Error)

 

n, _ := f.Read(buf)

错误处理

func Foo(param int)(n int, err error) {
// ...
}
调用时的代码建议按如下方式处理错误情况:
n, err := Foo(0)
if err != nil {
// 错误处理
} else {
// 使用返回值n
}


func Stat(name string) (fi FileInfo, err error) {
var stat syscall.Stat_t
err = syscall.Stat(name, &stat)
if err != nil {
return nil, &PathError{"stat", name, err}
}
return fileInfoFromStat(&stat, name), nil
}

 defer

//defer 执行一些清理和维护性的工作defer语句的调用是遵照
//先进后出的原则,即最后一个defer语句将最先被执行。

func CopyFile(dst, src string) (w int64, err error) {
srcFile, err := os.Open(src)
if err != nil {
return
}
defer srcFile.Close()
dstFile, err := os.Create(dstName)
if err != nil {
return
}
defer dstFile.Close()
return io.Copy(dstFile, srcFile)
}

panic()recover() 

Go语言引入了两个内置函数panic()recover()以报告和处理运行时错误和程序中的错

误场景:
func panic(interface{})
func recover() interface{}


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:gaojy

查看原文:Golang

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1115 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传