go语言基础-数据类型&函数&结构体&条件&循环&指针

语言结构

组成部分

包声明
引入包
函数
变量
语句 & 表达式
注释

数据类型

数据类型

布尔型
数字类型:支持复数
字符串类型:UTF-8编码标识Unicode
派生类型:
    包括:
    (a) 指针类型(Pointer)
    (b) 数组类型
    (c) 结构化类型(struct)
    (d) Channel 类型
    (e) 函数类型
    (f) 切片类型
    (g) 接口类型(interface)
    (h) Map 类型

数字类型

uint8       无符号 8 位整型 (0 到 255)
uint16      无符号 16 位整型 (0 到 65535)
uint32      无符号 32 位整型 (0 到 4294967295)
uint64      无符号 64 位整型 (0 到 18446744073709551615)
int8        有符号 8 位整型 (-128 到 127)
int16       有符号 16 位整型 (-32768 到 32767)
int32       有符号 32 位整型 (-2147483648 到 2147483647)
int64       有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)

浮点型

float32     IEEE-754 32位浮点型数
float64     IEEE-754 64位浮点型数
complex64   32 位实数和虚数
complex128  64 位实数和虚数

其他数字类型

byte        类似 uint8rune
rune        类似 int32
uint        32 或 64 位
int         与 uint 一样大小
uintptr     无符号整型,用于存放一个指针

变量

三种方式

var a int = 10  
var b = 10      //自动分配类型
c : = 10

多变量声明

//类型相同多个变量, 非全局变量
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
)

其他情况

var a, b, c int
a, b, c = 5, 7, "abc"
a, b, c := 5, 7, "abc"
_, b = 5, 7 
//_是只写变量,相当与抛弃5

值类型和引用类型
:=
只能用于函数体内

常量

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

iota

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
)
package main

import "fmt"
const (
	i=1<<iota
    j=3<<iota
    k
    l
)

func main() {
	fmt.Println("i=",i)
	fmt.Println("j=",j)
	fmt.Println("k=",k)
	fmt.Println("l=",l)
}

结果为

i= 1
j= 6
k= 12
l= 24

iota表示从0开始自动加1,所以i=1<<0,j=3<<1(<<表示左移的意思),即:i=1,j=6,这没问题,关键在k和l,从输出结果看,k=3<<2,l=3<<3。

运算符号

位运算

& | ^ << >>

其他

&   实际地址
*   指针

条件语句

if

if a < 20 {
       /* 如果条件为 true 则执行以下语句 */
       fmt.Printf("a 小于 20\n" )
   }
   

switch

    switch marks {
      case 90: grade = "A"
      case 80: grade = "B"
      case 50,60,70 : grade = "C"
      default: grade = "D"  
    }
    
    switch {
      case grade == "A" :
         fmt.Printf("优秀!\n" )     
      case grade == "B", grade == "C" :
         fmt.Printf("良好\n" )      
      case grade == "D" :
         fmt.Printf("及格\n" )      
      case grade == "F":
         fmt.Printf("不及格\n" )
      default:
         fmt.Printf("差\n" );
    }
   
    var x interface{}
    switch i := x.(type) {
     case nil:	  
        fmt.Printf(" x 的类型 :%T",i)                
     case int:	  
        fmt.Printf("x 是 int 型")                       
     case float64:
        fmt.Printf("x 是 float64 型")           
     case func(int) float64:
        fmt.Printf("x 是 func(int) 型")                      
     case bool, string:
        fmt.Printf("x 是 bool 或 string 型" )       
     default:
        fmt.Printf("未知型")     
    }  

select语句
每个case必须是一个通信操作,要么是发送要么是接收;
select随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句应该总是可运行的。

func main() {
   var c1, c2, c3 chan int
   var i1, i2 int
   select {
      case i1 = <-c1:
         fmt.Printf("received ", i1, " from c1\n")
      case c2 <- i2:
         fmt.Printf("sent ", i2, " to c2\n")
      case i3, ok := (<-c3):  // same as: i3, ok := <-c3
         if ok {
            fmt.Printf("received ", i3, " from c3\n")
         } else {
            fmt.Printf("c3 is closed\n")
         }
      default:
         fmt.Printf("no communication\n")
   }    
}

循环语句

for

//和 C 语言的 for 一样:
for init; condition; post { }
//和 C 的 while 一样:
for condition { }
//和 C 的 for(;;) 一样:
for { }

post: 一般为赋值表达式,给控制变量增量或减量。
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。

for key, value := range oldMap {
    newMap[key] = value
}

例子

package main
import "fmt"

func main() {

   var b int = 15
   var a int
   numbers := [6]int{1, 2, 3, 5} 

   /* for 循环 */
   for a := 0; a < 10; a++ {
      fmt.Printf("a 的值为: %d\n", a)
   }

   for a < b {
      a++
      fmt.Printf("a 的值为: %d\n", a)
      }

   for i,x:= range numbers {
      fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
   }   
}

goto

package main
import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 10

   /* 循环 */
   LOOP: for a < 20 {
      if a == 15 {
         /* 跳过迭代 */
         a = a + 1
         goto LOOP
      }
      fmt.Printf("a的值为 : %d\n", a)
      a++     
   }  
}

无限循环

package main
import "fmt"

func main() {
    for true  {
        fmt.Printf("这是无限循环。\n");
    }
}

函数

格式

func function_name( [parameter list] ) [return_types] {
   函数体
}

例子

/* 函数返回两个数的最大值 */
func max(num1, num2 int) int {
   /* 声明局部变量 */
   var result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result 
}

多个返回值

package main
import "fmt"

func swap(x, y string) (string, string) {
   return y, x
}

func main() {
   a, b := swap("Mahesh", "Kumar")
   fmt.Println(a, b)
}

参数传递
值传递
引用传递

函数作为值

package main
import (
   "fmt"
   "math"
)

func main(){
   /* 声明函数变量 */
   getSquareRoot := func(x float64) float64 {
      return math.Sqrt(x)
   }

   /* 使用函数 */
   fmt.Println(getSquareRoot(9))

}

闭包
匿名函数,可作为闭包

package main
import "fmt"

func getSequence() func() int {
   i:=0
   return func() int {
      i+=1
     return i  
   }
}

func main(){
   /* nextNumber 为一个函数,函数 i 为 0 */
   nextNumber := getSequence()  

   /* 调用 nextNumber 函数,i 变量自增 1 并返回 */
   fmt.Println(nextNumber())
   fmt.Println(nextNumber())
   fmt.Println(nextNumber())
   
   /* 创建新的函数 nextNumber1,并查看结果 */
   nextNumber1 := getSequence()  
   fmt.Println(nextNumber1())
   fmt.Println(nextNumber1())
}
//输出
1
2
3
1
2

方法

func (variable_name variable_data_type) function_name() [return_type]{
   /* 函数体*/
}

这个挺有意思。。。

package main
import (
   "fmt"  
)

/* 定义函数 */
type Circle struct {
  radius float64
}

func main() {
  var c1 Circle
  c1.radius = 10.00
  fmt.Println("Area of Circle(c1) = ", c1.getArea())
}

//该 method 属于 Circle 类型对象中的方法
func (c Circle) getArea() float64 {
  //c.radius 即为 Circle 类型对象中的属性
  return 3.14 * c.radius * c.radius
}

变量作用于

全局:初始化的默认值

int	0
float32	0
pointer	nil

局部
形参

数组

//定义
var balance [10] float32
//初始化
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
//设置后面的值
balance[4] = 50.0
//访问数组
float32 salary = balance[9]

多维数组

var threedim [5][10][4]int

初始化二维数组

a = [3][4]int{  
 {0, 1, 2, 3} ,   /*  第一行索引为 0 */
 {4, 5, 6, 7} ,   /*  第二行索引为 1 */
 {8, 9, 10, 11}   /*  第三行索引为 2 */
}

向函数传递数组
形参

void myFunction(param [10]int) {
}
//这种形式一般要再传入数组大小
void myFunction(param []int) {
}

指针

package main
import "fmt"

func main() {
   var a int = 10   
   fmt.Printf("变量的地址: %x\n", &a  )
}
var ip *int        /* 指向整型*/
var fp *float32    /* 指向浮点型 */
package main

import "fmt"

func main() {
   var a int= 20   /* 声明实际变量 */
   var ip *int        /* 声明指针变量 */

   ip = &a  /* 指针变量的存储地址 */

   fmt.Printf("a 变量的地址是: %x\n", &a  )

   /* 指针变量的存储地址 */
   fmt.Printf("ip 变量储存的指针地址: %x\n", ip )

   /* 使用指针访问值 */
   fmt.Printf("*ip 变量的值: %d\n", *ip )
}

空指针nil

package main
import "fmt"

func main() {
   var ptr *int
   fmt.Printf("ptr 的值为 : %x\n", ptr  )
}

空指针判断

if(ptr != nil)     /* ptr 不是空指针 */
if(ptr == nil)    /* ptr 是空指针 */

指针数组

package main
import "fmt"
const MAX int = 3

func main() {
   a := []int{10,100,200}
   var i int
   var ptr [MAX]*int;

   for  i = 0; i < MAX; i++ {
      ptr[i] = &a[i] /* 整数地址赋值给指针数组 */
   }

   for  i = 0; i < MAX; i++ {
      fmt.Printf("a[%d] = %d\n", i,*ptr[i] )
   }
}

指向指针的指针

package main
import "fmt"
func main() {

   var a int
   var ptr *int
   var pptr **int

   a = 3000

   /* 指针 ptr 地址 */
   ptr = &a

   /* 指向指针 ptr 地址 */
   pptr = &ptr

   /* 获取 pptr 的值 */
   fmt.Printf("变量 a = %d\n", a )
   fmt.Printf("指针变量 *ptr = %d\n", *ptr )
   fmt.Printf("指向指针的指针变量 **pptr = %d\n", **pptr)
}

指针作为函数参数

package main
import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 100
   var b int= 200

   fmt.Printf("交换前 a 的值 : %d\n", a )
   fmt.Printf("交换前 b 的值 : %d\n", b )

   /* 调用函数用于交换值
   * &a 指向 a 变量的地址
   * &b 指向 b 变量的地址
   */
   swap(&a, &b);

   fmt.Printf("交换后 a 的值 : %d\n", a )
   fmt.Printf("交换后 b 的值 : %d\n", b )
}

func swap(x *int, y *int) {
   var temp int
   temp = *x    /* 保存 x 地址的值 */
   *x = *y      /* 将 y 赋值给 x */
   *y = temp    /* 将 temp 赋值给 y */
}

结构体

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

作为参数

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 信息 */
   printBook(Book1)

   /* 打印 Book2 信息 */
   printBook(Book2)
}

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);
}

结构体指针

package main
import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}

func main() {
   var Book1 Books        /* Declare Book1 of type Book */
   var Book2 Books        /* Declare Book2 of type Book */

   /* 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 信息 */
   printBook(&Book1)

   /* 打印 Book2 信息 */
   printBook(&Book2)
}
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);
}
posted @ 2017-03-24 09:49  zhangshihai1232  阅读(142)  评论(0)    收藏  举报