1. 小案例:

package main   定义了包名 

import "fmt"  告诉 Go 编译器这个程序需要使用 fmt 包

 

func main() {  程序开始执行的函数

   /* 这是我的第一个简单的程序 */

   fmt.Println("Hello, World!")}  字符串输出到控制台

go语言数据类型:

  1. 布尔型: var b bool = true。
  2. 数据类型: 整数型  int ; 浮点类型: float
  3. 字符串类型:String

 (a) 指针类型(Pointer

  • (b) 数组类型
  • (c) 结构化类型(struct)
  • (d) Channel 类型
  • (e) 函数类型
  • (f) 切片类型
  • (g) 接口类型(interface
  • (h) Map 类型

变量声明:

Var a int = 10 ;第一种

a :=10 ; 省略var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误。

多变量声明:

//类型相同多个变量, 非全局变量var vname1, vname2, vname3 type

vname1, vname2, vname3 = v1, v2, v3

var vname1, vname2, vname3 = v1, v2, v3 //和python很像,不需要显示声明类型,自动推断

 

vname1, vname2, vname3 := v1, v2, v3 //出现在:=左侧的变量不应该是已经被声明过的,否则会导致编译错误

 

 

var (

    vname1 v_type1

    vname2 v_type2 )// 这种因式分解关键字的写法一般用于声明全局变量

注意事项:

如果在相同的代码块中,我们不可以再次对于相同名称的变量使用初始化声明,例如:a := 20 就是不被允许的,编译器会提示错误 no new variables on left side of :=,但是 a = 20 是可以的,因为这是给相同的变量赋予一个新的值。

 

你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。

  • 显式类型定义: const b string = "abc"
  • 隐式类型定义: const b = "abc"

多个相同类型的声明:

const c_name1, c_name2 = value1, value2   //const关键字    修饰的数据类型是指常类型,常类型的变量或对象的值是不能被更新的

 

常量可以用len()字符串长度, cap()数组长度, unsafe.Sizeof()字节长度 函数计算表达式的值

 

iota,特殊常量,可以认为是一个可以被编译器修改的常量。

在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1。

 iota 可以被用作枚举值:

const (

    a = iota

    b = iota

    c = iota)

第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式:

例子1:const (

    a = iota

    b

    c)

例子2:

 const (

            a = iota   //0

            b          //1

            c          //2

            d = "ha"   //独立值,iota += 1

            e          //"ha"   iota += 1

            f = 100    //iota +=1

            g          //100  iota +=1

            h = iota   //7,恢复计数

            i          //8

    )

 

算术运算符:

下表列出了所有Go语言的算术运算符。假定 A 值为 10,B 值为 20。

+

相加

A + B 输出结果 30

-

相减

A - B 输出结果 -10

*

相乘

A * B 输出结果 200

/

相除

B / A 输出结果 2

%

求余

B % A 输出结果 0

++

自增

A++ 输出结果 11

--

自减

A-- 输出结果 9

 

关系运算符:

假定 A 值为 10,B 值为 20。

==

检查两个值是否相等,如果相等返回 True 否则返回 False。

(A == B) 为 False

!=

检查两个值是否不相等,如果不相等返回 True 否则返回 False。

(A != B) 为 True

>

检查左边值是否大于右边值,如果是返回 True 否则返回 False。

(A > B) 为 False

<

检查左边值是否小于右边值,如果是返回 True 否则返回 False。

(A < B) 为 True

>=

检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。

(A >= B) 为 False

<=

检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。

 

 

逻辑运算符:

假定 A 值为 True,B 值为 False

&&

逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。

(A && B) 为 False

||

逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。

(A || B) 为 True

!

逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。

!(A && B) 为 True

赋值运算符

=

简单的赋值运算符,将一个表达式的值赋给一个左值

C = A + B 将 A + B 表达式结果赋值给 C

+=

相加后再赋值

C += A 等于 C = C + A

-=

相减后再赋值

C -= A 等于 C = C - A

*=

相乘后再赋值

C *= A 等于 C = C * A

/=

相除后再赋值

C /= A 等于 C = C / A

%=

求余后再赋值

C %= A 等于 C = C % A

<<=

左移后赋值

C <<= 2 等于 C = C << 2

>>=

右移后赋值

C >>= 2 等于 C = C >> 2

&=

按位与后赋值

C &= 2 等于 C = C & 2

^=

按位异或后赋值

C ^= 2 等于 C = C ^ 2

|=

按位或后赋值

C |= 2 等于 C = C | 2

语言条件语句

if 语句

if 语句 由一个布尔表达式后紧跟一个或多个语句组成。

if...else 语句

if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。

if 嵌套语句

你可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句。

switch 语句

switch 语句用于基于不同条件执行不同动作。

select 语句

select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。

循环语句:

for 循环 

重复执行语句块

循环嵌套 

在 for 循环中嵌套一个或多个 for 循环

循环控制语句:

break 语句 

经常用于中断当前 for 循环或跳出 switch 语句

continue 语句 

跳过当前循环的剩余语句,然后继续进行下一轮循环。

goto 语句 

将控制转移到被标记的语句。

 

 

 

无限循环: 通过 for 循环语句中只设置一个条件表达式来执行无限循环

package main

import "fmt"

 

func main() {

    for true  {

        fmt.Printf("这是无限循环。\n");

    }}

函数定义:

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 }

注意: 在函数内码不能改变用来调用所述函数的参数。考虑函数swap()的定义

 

Go 函数 局部变量 与  全局变量: 

局部变量:

在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。

package main

import "fmt"

 

func main() {

   /* 声明局部变量 */

   var a, b, c int

 

   /* 初始化参数 */

   a = 10

   b = 20

   c = a + b

 

   fmt.Printf ("结果: a = %d, b = %d and c = %d\n", a, b, c)}

全局变量

在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用。

全局变量可以在任何函数中使用,以下实例演示了如何使用全局变量:

package main

import "fmt"

/* 声明全局变量 */

var g int

 

func main() {

 

   /* 声明局部变量 */

   var a, b int

 

   /* 初始化参数 */

   a = 10

   b = 20

   g = a + b

 

   fmt.Printf("结果: a = %d, b = %d and g = %d\n", a, b, g)}

注意:  Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑

 

Go 语言数组:

声明数组:

var variable_name [SIZE] variable_type

例子:

package main

import "fmt"

 

func main() {

   var n [10]int /* n 是一个长度为 10 的数组 */

   var i,j int

 

   /* 为数组 n 初始化元素 */         

   for i = 0; i < 10; i++ {

      n[i] = i + 100 /* 设置元素为 i + 100 */

   }

 

   /* 输出每个数组元素的值 */

   for j = 0; j < 10; j++ {

      fmt.Printf("Element[%d] = %d\n", j, n[j] )

   }}

Go语言结构体:

:

package main

import "fmt"

 

type Books struct {

   title string

   author string

   subject string

   book_id int}

 

func main() {

   var Book1 Books        /* 声明 Book1 为 Books 类型 */

   var Book2 Books        /* 声明 Book2 为 Books 类型 */

 

   /* book 1 描述 */

   Book1.title = "Go 语言"

   Book1.author = "www.runoob.com"

   Book1.subject = "Go 语言教程"

   Book1.book_id = 6495407

 

   /* book 2 描述 */

   Book2.title = "Python 教程"

   Book2.author = "www.runoob.com"

   Book2.subject = "Python 语言教程"

   Book2.book_id = 6495700

 

   /* 打印 Book1 信息 */

   fmt.Printf( "Book 1 title : %s\n", Book1.title)

   fmt.Printf( "Book 1 author : %s\n", Book1.author)

   fmt.Printf( "Book 1 subject : %s\n", Book1.subject)

   fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)

 

   /* 打印 Book2 信息 */

   fmt.Printf( "Book 2 title : %s\n", Book2.title)

   fmt.Printf( "Book 2 author : %s\n", Book2.author)

   fmt.Printf( "Book 2 subject : %s\n", Book2.subject)

   fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id)

//第二种  结构体作为函数参

func printBook( book Books ) {

   fmt.Printf( "Book title : %s\n", book.title);

   fmt.Printf( "Book author : %s\n", book.author);

   fmt.Printf( "Book subject : %s\n", book.subject);

   fmt.Printf( "Book book_id : %d\n", book.book_id);

 

}

 

Go语言切片:

go语言切片是数组的对象.

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

定义切片: var identifier []type

切片不需要长度

或者使用make() 函数来创建切片

var slice1 []type = make([]type, len)

也可以简写为

slice1 := make([]type, len)

:    slice2 := make([]int32, 9)
    slice3 := []int32{}

len() 和 cap() 函数

切片是可索引的,并且可以由 len() 方法获取长度。

切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。

注意:切片的零值为 nil 。对于切片的零值, len 和 cap 都将返回0。

追加使用append()方法   复制使用copy()方法.

实际的是获取数组的某一部分,len切片<=cap切片<=len数组,切片由三部分组成:指向底层数组的指针、len、cap。

Go语言范围:

Go语言中 range 关键字用于for循环迭代数组(array) 切片(slice) 通道(channel) 或者集合(map)的元素, 在数组和切片中返回元素的索引值,在集合中返回key-value 对的key.

实例:

package mainimport "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 -> banana0 1031 111

 

 

Go语言Map:

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

实例:

package main

import "fmt"

 

func main() {

   var countryCapitalMap map[string]string

   /* 创建集合 */

   countryCapitalMap = make(map[string]string)

   

   /* map 插入 key-value 对,各个国家对应的首都 */

   countryCapitalMap["France"] = "Paris"

   countryCapitalMap["Italy"] = "Rome"

   countryCapitalMap["Japan"] = "Tokyo"

   countryCapitalMap["India"] = "New Delhi"

   

   /* 使用 key 输出 map 值 */

   for country := range countryCapitalMap {

      fmt.Println("Capital of",country,"is",countryCapitalMap[country])

   }

   

   /* 查看元素在集合中是否存在 */

   captial, ok := countryCapitalMap["United States"]

   /* 如果 ok 是 true, 则存在,否则不存在 */

   if(ok){

      fmt.Println("Capital of United States is", captial)  

   }else {

      fmt.Println("Capital of United States is not present")

   }}

Delete 函数: 闪出集合元素  ,参数为map和对应的key

例子:

package main

import "fmt

func main() {   

   /* 创建 map */

   countryCapitalMap := map[string] string {"France":"Paris","Italy":"Rome","Japan":"Tokyo","India":"New Delhi"}

   fmt.Println("原始 map")   

   /* 打印 map */

   for country := range countryCapitalMap {

      fmt.Println("Capital of",country,"is",countryCapitalMap[country])

   }

   /* 删除元素 */

   delete(countryCapitalMap,"France");

   fmt.Println("Entry for France is deleted")  

   fmt.Println("删除元素后 map")   

   /* 打印 map */

   for country := range countryCapitalMap {

      fmt.Println("Capital of",country,"is",countryCapitalMap[country])

   }}

Go语言递归调用函数:

递归就是运行过程中调用自己.

例子:

阶乘:

package main

import "fmt"

func Factorial(n uint64)(result uint64) {

    if (n > 0) {

        result = n * Factorial(n-1)//递归

        return result

    }

    return 1}

func main() {  

    var i int = 15

fmt.Printf("%d 的阶乘是 %d\n", i, Factorial(uint64(i)))}

菲波那切数列(兔子数列):

package main

import "fmt"

 

func fibonacci(n int) int {

  if n < 2 {

   return n

  }

  return fibonacci(n-2) + fibonacci(n-1)}

 

func main() {

    var i int

    for i = 0; i < 10; i++ {

       fmt.Printf("%d\t", fibonacci(i))

    }}

结果:

0    1    1    2    3    5    8    13    21    34

Go语言类型转化:

: 将整数型转化为浮点类型;

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语言接口:

实现接口中的方法就是实现了 这个接口.

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()

}

在上面的例子中,我们定义了一个接口Phone,接口里面有一个方法call()。然后我们在main函数里面定义了一个Phone类型变量,并分别为之赋值为NokiaPhone和IPhone。然后调用call()方法.

 

Go语言处理错误:

Go语言通过内置的错误接口提供非常简单的错误处理机制.

Error 类型是一个接口,定义:

type error interface {

Error() string

}

函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息:

func Sqrt(f float64) (float64, error) {

    if f < 0 {

        return 0, errors.New("math: square root of negative number")

    }

    // 实现}

实例:

package main

import (

    "fmt")

// 定义一个 DivideError 结构

type DivideError struct {

    dividee int

    divider int}

// 实现     `error` 接口

func (de *DivideError) Error() string {

    strFormat := `

    Cannot proceed, the divider is zero.

    dividee: %d

    divider: 0

`

    return fmt.Sprintf(strFormat, de.dividee)}

// 定义 `int` 类型除法运算的函数

func Divide(varDividee int, varDivider int) (result int, errorMsg string) {

    if varDivider == 0 {

        dData := DivideError{

            dividee: varDividee,

            divider: varDivider,

        }

        errorMsg = dData.Error()

        return

    } else {

        return varDividee / varDivider, ""

    }

}

 

func main() {

 

    // 正常情况

    if result, errorMsg := Divide(100, 10); errorMsg == "" {

        fmt.Println("100/10 = ", result)

    }

    // 当被除数为零的时候会返回错误信息

    if _, errorMsg := Divide(100, 0); errorMsg != "" {

        fmt.Println("errorMsg is: ", errorMsg)

    }

}

 

posted on 2018-03-21 18:15  奋斗的小菜鸟+1  阅读(149)  评论(0编辑  收藏  举报