要一直走下去

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1-5 目录结构

 

 

 “包”在go文件第一行进行指定。

如果两个go文件都属于main包,可以直接调用。

例如,两个go文件都属于main包,test.go和main.go

要用  `go  run test.go  main.go`命令,因为main包默认不会加载其他文件  

 

  

                  

 

  

 

 

1-6:go的基本命令

  1.    `go run src/github.com/xx/hello.go`           //原理也是先编译再运行
  2.    `go build -o bin/hello.exe github.com/xx/hello`
  3.    `go install github.com/xx/hello`             //安装可执行文件到bin目录下,要配置 "GOBIN" 环境变量
  4.    `go test`                          //执行单元测试或压力测试
  5.    `go env`                        //go环境变量,GOPATH是环境变量
  6.    `go fmt github.com/xx/hello.go`             //格式化源代码
  • 单行注释 //
  • 多行注释 /* */

 

1-7:go语言特性

  • 垃圾回收
  1. 内存自动回收,再也不需要开发人员管理内存
  2. 开发人员专注业务实现,降低心智负担
  3. 只需要new分配内存,不需要释放
  • 天然并发
  1. 从语言层面支持并发,非常简单。只需要go一下(go是启动线程吗??不知道
  2. goroutine,轻量级线程,创建成千上万个goroute称为可能
  3. 基于CSP(通讯序列进程)模型实现
package main

import (
    "fmt"
    "time"
)

func cal(){
    fmt.Println("开始进行大量计算...")
    time.Sleep(time.Second*2)
}

func main(){
    go cal()
    fmt.Println("主线程完成")
    time.Sleep(time.Second * 3)
}
  • channel
  1. 管道,类似unix/linux中的pipe
  2. 多个goroute直接通过channel进行通信
  3. 定义全局pipe进行通信
  4. package main

    import(
        "fmt"
    )

    var pipe chan int   //定义全局pipe进行goroute通信,如果全局定义了多个pipe会分不清,不建议用全局的pipe进行通信

    func add(a int, b int) int {
        sum := a + b
    pipe <- sum   //结果扔进管道
        return sum
    }

    func main() {
        pipe = make(chan int, 1)
        go add(2, 5)
    sum := <- pipe  //阻塞,管道有值才返回
        fmt.Println("sum=", sum)
    }
  5. pipe传参进行通信

 

package main


import(
    "fmt"
)

func add(a int, b int, p chan int) int {
    sum := a + b
    p <- sum   //结果扔进管道
    return sum
}

func main() {
    pipe := make(chan int, 1)
    go add(2, 5, pipe)
    sum := <- pipe  //阻塞,管道有值才返回
    fmt.Println("sum=", sum)
}

 

  1. 支持任何类型(字符整数类都可以放进管道)
package main

import(
    "fmt"
)

func testPipe() {
    pipe := make(chan int, 3)   //定义管道,管道长度3,存放int,管道是队列的数据结构
    pipe <- 1            // 向管道中放数据
    pipe <- 2
    pipe <- 3
    fmt.Printf("取出前:%d", len(pipe))    // 3
    //从管道取出放入变量a中
    a := <- pipe
    fmt.Printf("取出:%d",a)    // 1
    fmt.Printf("取出后:%d", len(pipe))  // 2
}
  • 多返回值
  1. 一个函数返回多个值

 

package main

import (
    "fmt"
)

func cal(a int, b int) (int, int) {
    return a + b, a -b 
}

func main(){
    a, b := cal(4, 5)
    x, _ := cal(5, 6)   // 如果只想用第一个数据,就用_忽略第二个
    fmt.Printf("a=%d, b=%d", a, b)
}

 

  • 编译型语言
  1. 性能只比c底10%
  2. 效率和python,PHP差不多

 

1-9 变量

  • 定义变量

var a int
var b string
var c bool
var d int = 8
var e string = "hello"

等价于

var(
  a int
  b string
  c bool
  d int = 8
  e string = "hello"
)

  • 格式化输出

var a int
var b bool
var c string
var d float32
fmt.Printf( "%d, %t, %s, %f"  ,a  ,b,  c,   d)      //注意:不是Println,必须是Printf

1-10 常量

  • 常量必须要赋值。  定义常量时,不写类型,go会进行推导    

const b string="hello"
const b = "hello"
const Pi = 3.1415926
const a = 9/2

或者

const (
  a int = 100
  b string = "hello"
)

 

 

  • 定义常量时某行不写,和上一行一样

const (
  a = iota           //iota默认值是0,后面b,c会自增变为1,2
  b                    //不写默认为b=iota
  c
)

 

const ( 
  a = 1 << iota           // 1 左移0位 = 1
  b                            // b = 1 << iota       1左移1位=2
  c                           // 1左移2位  = 4
)

 

1-11常量练习

const (
  A=iota
  B
  C
  D = 8
  E
  F = iota
  G
)

const (
  A1 = iota
  A2
)

ABCDEFG是多少?
A=0, B=1, C=2, D=8, E=8, F=5, G=6
A1=0, A2=1

总结: 1.iota在const()内生效         2.iota隔一行新增1

 

1-12 数据类型

  • 布尔类型

var b bool

var b bool=true

var b = false       //布尔类型没有赋值默认为false

等于 ==  、 不等于 != 、 取反 !b 、 &&逻辑与(前面为假不执行后面) 、  || 逻辑或(前面为真不执行后面) 、

 

 

 


      格式化输出占位符:%t

  • 整数和浮点数
  1. int8、int16、int32、int64 (整型,可正可负,后面的数字是二进制位)
  2. unit8、unit16、unit32、unit64 (无符号整数,只能存正数)
  3. int和unit,和操作系统平台相关 (32位平台占4字节,64位平台占8字节)
  4. float32和float64浮点类型
  5. 所有整数初始化为0,所有浮点数初始化为0.0,布尔类型初始化为false

  说明:

  1. Go是强类型语言,不同类型相加以及赋值是不允许的
  2. 那怎样才能实现不同类型相加呢? 要强转 int(a)
  3. 输出占位符,整数%d 十六进制%x 浮点数%f

 

字符类型

字符是单个字符,用单引号,字符串用双引号,字符ASCII编码的

package main

import(
    "fmt"
)

func main() {
    var b byte = 'a'   
    fmt.Println(b)   // 97
    fmt.Printf("%c", b)  // a
}

 

1-13 数据类型-字符串

var str string

var str string = "hello world"

 

  • 字符串占位符  %s
  • 万能输出占位符%v 不知道用什么占位符可以用%v
  • c := "hello" 语句 , 用 := 的方式。省略了var string c 的过程
  • 字符串两种表示方式:双引号"xxx"  反引号`xx`里面全转义

字符串常用操作

  1. 长度:len(str)
  2. 拼接:+, fmt.Sprintf("%s%s", string1, string2)
  3. 分割:strings.Split(string1, ";") // package "strings" 返回数组
  4. 包含:strings.Contains("xx")
  5. 前缀或后缀判断:strings.HasPrefix("xx.com","xx"), strings.HasSuffix("ff.yy","yy")
  6. 子串出现的位置:从前往后strings.Index(string1, "xx"), 从后往前strings.LastIndex(string1, "xx")
  7. join操作:strings.Join(a[]string, sep string)
var strArr []string = []string{"aa", "bb", "cc"}
resultStr := strings.Join(strArr, ";")
fmt.Printf("result=%s\n", resultStr) //aa;bb;cc

 

 

报错,编译型语言要把操作放在函数里才行。

 

全局只能进行声明和初始化, var a int = 1 这种是编译的时候初始化, a := 1这种是执行的时候初始化

 

posted on 2020-06-24 02:04  要一直走下去  阅读(184)  评论(0编辑  收藏  举报