跳转底部

go基础

unsafe推荐博客:https://blog.csdn.net/hzwy23/article/details/60893765

按位运算符(>> << ~ & ^ | )及实例

^就是异或操作,相同为0,相异为1

双目运算符

fmt.Println(0&^0)       //0
fmt.Println(0&^1)  //0
fmt.Println(1&^0)  //1
fmt.Println(1&^1)  //0

1、如果右侧是0,则左侧数保持不变

2、如果右侧是1,则左侧数一定清零

3、功能同a&(^b)相同

4、如果左侧是变量,也等同于:

var a int

a &^= b

和它等价的c语言运算符表达式:

等价于c语言里的&=~

例如c语言的写法:

int a = 3;

a &= ~1;

 

各种运算符的优先级,详见菜鸟教程:http://www.runoob.com/go/go-operators.html 

 

&a; 将给出变量的实际地址。

*a; 是一个指针变量

package main

import "fmt"

func main() {
   var a int = 4
   var b int32
   var c float32
   var ptr *int

   /* 运算符实例 */
   fmt.Printf("第 1 行 - a 变量类型为 = %T\n", a );
   fmt.Printf("第 2 行 - b 变量类型为 = %T\n", b );
   fmt.Printf("第 3 行 - c 变量类型为 = %T\n", c );

   /*  & 和 * 运算符实例 */
   ptr = &a    /* 'ptr' 包含了 'a' 变量的地址 */
   fmt.Printf("a 的值为  %d\n", a);
   fmt.Printf("*ptr 为 %d\n", *ptr);
}

第 1 行 - a 变量类型为 = int
第 2 行 - b 变量类型为 = int32
第 3 行 - c 变量类型为 = float32
a 的值为  4
*ptr 为 4

  

 

switch var1 {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}

select是Go中的一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收。

select随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句应该总是可运行的。

select {
    case communication clause  :
       statement(s);      
    case communication clause  :
       statement(s); 
    /* 你可以定义任意数量的 case */
    default : /* 可选 */
       statement(s);
}


以下描述了 select 语句的语法:

    • 每个case都必须是一个通信
    • 所有channel表达式都会被求值
    • 所有被发送的表达式都会被求值
    • 如果任意某个通信可以进行,它就执行;其他被忽略。
    • 如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。 
      否则:
      1. 如果有default子句,则执行该语句。
      2. 如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。
package main

import "fmt"

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

  

以上代码执行结果为:

no communication

Channel是Go中的一个核心类型,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication)。

它的操作符是箭头 <- 。 

  1. ch <- v // 发送值v到Channel ch中 
  2. v := <-ch // 从Channel ch中接收数据,并将数据赋值给v 

(箭头的指向就是数据的流向)

就像 map 和 slice 数据类型一样, channel必须先创建再使用:

ch := make(chan int)  详见博客:https://blog.csdn.net/whatday/article/details/74453089

for循环

package main

import "fmt"

func main() {

   var b int = 15
   var a int

   numbers := [6]int{1, 2, 3, 5}   //numbers是个数组,6位,前4位是 1,2,3,5后面两位是0

   /* 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 {    //第三种形式  ,range获取可迭代元素的索引和值
      fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
   }   
}

  Go 语言的 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++     
   }  
}

 函数

值传递 值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递 引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

普通函数

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

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

匿名函数,匿名函数的优越性在于可以直接使用函数内的变量,不必申明
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())    //1
   fmt.Println(nextNumber())    //2
   fmt.Println(nextNumber())    //3
   
   /* 创建新的函数 nextNumber1,并查看结果 */
   nextNumber1 := getSequence()  
   fmt.Println(nextNumber1())   //1
   fmt.Println(nextNumber1())   //2
}

  

方法  
Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。就是给接受者赋予了一个新的方法
语法格式如下
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("圆的面积 = ", c1.getArea())
}

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

 局部变量和全局变量

package main

import "fmt"

func main(){
  var a int = 0
  fmt.Println("for start")
  for a:=0; a < 10; a++ {
    fmt.Println(a)
  }
  fmt.Println("for end")

  fmt.Println(a)
}

 在 for 循环的 初始化initialize(a:=0) 中,此时 initialize 中的 a 与外层的 a 不是同一个变量,initialize 中的 a 为 for 循环中的局部变量,因此在执行完 for 循环后,输出 a 的值仍然为 0




posted on 2018-10-29 19:06  afly666  阅读(142)  评论(0)    收藏  举报

导航

回到顶部