GO 语言快速学习 | PHP转GO笔记

GO 语言快速学习 | PHP转GO笔记,第1张

概述web框架流行度排行https://github.com/speedwheel/awesome-go-web-frameworks/blob/master/README.md#popularitybeegohttps://beego.me/productsechohttps://echo.labstack.com/gingo社区文档https://learnku.com/docs/gin-gonic/2019看云gin文档http web框架

流行度排行

https://github.com/speedwheel/awesome-go-web-frameworks/blob/master/README.md#popularity

beego

https://beego.me/products

echo

https://echo.labstack.com/

gin go社区文档

https://learnku.com/docs/gin-gonic/2019

看云gin文档

https://www.kancloud.cn/shuangdeyu/gin_book/949418

gin快速使用

https://www.jianshu.com/p/98965b3ff638

gin-admin-vue

https://www.gin-vue-admin.com/docs/gorm

官网

https://golang.org/dl/

中文官网

https://go-zh.org/pkg/

go常用库

https://github.com/jobbole/awesome-go-cn

查看版本号

go version

查看env

go env

==拉不下来包==

export GOPATH=/usr/local/go/binexport goproxy=https://goproxy.ioexport PATH=$PATH:$GOPATHexport GO111MODulE=on

开启module

go env -w GO111MODulE=on

设置代理

go env -w goproxy=https://goproxy.io,direct

微服务框架

go-kit

go micro

go-zero

常用网址

go基础知识

go基础知识v1

go基础知识v2---micro

菜鸟GO

文档和技术论坛

gomod 详细使用

go官网库

==go官方pkg中文==

github对pgk的使用例子

go mod使用

基本数据类型

字符串 *** 作

本地gorm struct生成

https://github.com/xxjwxc/gormt.git

本地struct生成

https://github.com/hantmac/fuckdb.git

1 使用docker-composer方式启动2 遇到docker容器不能链接本地MysqL的时候 在本地MysqLGRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;FLUSH PRIVILEGES
struct 生成

go get -u github.com/gohouse/converter

err := converter.Newtable2Struct().    SavePath("./model.go").    Dsn("root:root@tcp(127.0.0.1:3306)/foroo_beta_shopify?charset=utf8").    TagKey("db").    EnableJsonTag(true).    table("fr_store").    Run()fmt.Println(err)return
基础

变量或者方法使用小写相当于protect 首字母大写 相当于public

使用+来拼接字符串

变量声明 var age int;

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

可以将 var f string = "Runoob" 简写为 f := "Runoob":

函数外的每个语句都必须以关键字开始(var、const、func等)

:=不能使用在函数外。

_多用于占位,表示忽略值。import _ "./hello" 用_占位只会执行导入包内的init,其他方法都不能调用

iota是go语言的常量计数器,只能在常量的表达式中使用

strconv.Itoa(97) 将一个数字转成字符串类型 string(97)go自带的会把数字转换成对应的ascii码

  const (            n1 = iota //0            n2        //1            n3        //2            n4        //3        )

map、slice、chan、指针、interface默认以引用的方式传递。

互斥锁 var lock sync.Mutex

var x int64var wg sync.WaitGroupvar lock sync.Mutexfunc add() {    for i := 0; i < 5000; i++ {        lock.Lock() // 加锁        x = x + 1        lock.Unlock() // 解锁    }    wg.Done()}func main() {    wg.Add(2)    go add()    go add()    wg.Wait()    fmt.Println(x)}

读写互斥锁 需要注意的是读写锁非常适合读多写少的场景,如果读和写的 *** 作差别不大,读写锁的优势就发挥不出来。

var (    x      int64    wg     sync.WaitGroup    lock   sync.Mutex    rwlock sync.RWMutex)func write() {    // lock.Lock()   // 加互斥锁    rwlock.Lock() // 加写锁    x = x + 1    time.Sleep(10 * time.Millisecond) // 假设读 *** 作耗时10毫秒    rwlock.Unlock()                   // 解写锁    // lock.Unlock()                     // 解互斥锁    wg.Done()}func read() {    // lock.Lock()                  // 加互斥锁    rwlock.RLock()               // 加读锁    time.Sleep(time.Millisecond) // 假设读 *** 作耗时1毫秒    rwlock.RUnlock()             // 解读锁    // lock.Unlock()                // 解互斥锁    wg.Done()}func main() {    start := time.Now()    for i := 0; i < 10; i++ {        wg.Add(1)        go write()    }    for i := 0; i < 1000; i++ {        wg.Add(1)        go read()    }    wg.Wait()    end := time.Now()    fmt.Println(end.Sub(start))}

sync.Once其实内部包含一个互斥锁和一个布尔值,互斥锁保证布尔值和数据的安全,而布尔值用来记录初始化是否完成。这样设计就能保证初始化 *** 作的时候是并发安全的并且初始化 *** 作也不会被执行多次。

var icons map[string]image.Imagevar loadIconsOnce sync.Oncefunc loadIcons() {    icons = map[string]image.Image{        "left":  loadIcon("left.png"),        "up":    loadIcon("up.png"),        "right": loadIcon("right.png"),        "down":  loadIcon("down.png"),    }}// Icon 是并发安全的func Icon(name string) image.Image {    loadIconsOnce.Do(loadIcons)    return icons[name]}

==goroutine高并发下 *** 作map 要用 sync.Map 来 *** 作==

//sync.Map内置了诸如Store、Load、LoadOrStore、Delete、Range等 *** 作方法var m = sync.Map{}func main() {    wg := sync.WaitGroup{}    for i := 0; i < 20; i++ {        wg.Add(1)        go func(n int) {            key := strconv.Itoa(n)            m.Store(key, n)            value, _ := m.Load(key)            fmt.Printf("k=:%v,v:=%v\n", key, value)            wg.Done()        }(i)    }    wg.Wait()}

==代码中的加锁 *** 作因为涉及内核态的上下文切换会比较耗时、代价比较高。针对基本数据类型我们还可以使用原子 *** 作来保证并发安全,因为原子 *** 作是Go语言提供的方法它在用户态就可以完成,因此性能比加锁 *** 作更好。Go语言中原子 *** 作由内置的标准库sync/atomic提供。==

// 原子 *** 作版加函数func atomicAdd() {    atomic.AddInt64(&x, 1)    wg.Done()}

make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身

变量之间使用引用地址直接可以改变

package mainfunc swap(a, b *int) {    var temp int    temp = *a    *a = *b    *b = temp}func main() {    var a, b = 1, 2    swap(&a, &b)    fmt.Println(a)    fmt.Println(b)}//指针小案例var a intfmt.Println(&a)var p *intp = &a*p = 20fmt.Println(a)

在参数赋值时可以不用用一个一个的赋值,可以直接传递一个数组或者切片,特别注意的是在参数后加上“…”即可

package mainimport (    "fmt")func test(s string, n ...int) string {    var x int    for _, i := range n {        x += i    }    return fmt.Sprintf(s, x)}func main() {    s := []int{1, 2, 3}    res := test("sum: %d", s...)    // slice... 展开slice    println(res)}

"_"标识符,用来忽略函数的某个返回值

没有参数的 return 语句返回各个返回变量的当前值。这种用法被称作“裸”返回。

func add(a, b int) (c int) {    c = a + b    return}func calc(a, b int) (sum int, avg int) {    sum = a + b    avg = (a + b) / 2    return}func main() {    var a, b int = 1, 2    c := add(a, b)    sum, avg := calc(a, b)    fmt.Println(a, b, c, sum, avg)}

命名返回参数允许 defer 延迟调用通过闭包读取和修改。

defer 是先进后出

package mainfunc add(x, y int) (z int) {    defer func() {        z += 100    }()    z = x + y    return}func main() {    println(add(1, 2)) }

定义一维数组

var a [5]int = [5]int{1,2,5,6,7}var a = [...]int{1,2,3,5,6} d := [...]struct {        name string        age  uint8    }{        {"user1", 10}, // 可省略元素类型。        {"user2", 20}, // 别忘了最后一行的逗号。    }

定义二维数组 第 2 纬度不能用 "..."

var b [3][2]int = [3][2]int{{1,2},{3,4},{5,6}}var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}

定义slice

全局:var arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}var slice0 []int = arr[start:end] var slice1 []int = arr[:end]        var slice2 []int = arr[start:]        var slice3 []int = arr[:] var slice4 = arr[:len(arr)-1]      //去掉切片的最后一个元素局部:arr2 := [...]int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}slice5 := arr[start:end]slice6 := arr[:end]        slice7 := arr[start:]     slice8 := arr[:]  slice9 := arr[:len(arr)-1] //去掉切片的最后一个元素//通过make来创建切片var slice []type = make([]type, len)slice  := make([]type, len)slice  := make([]type, len, cap)

定义map

    scoreMap := make(map[string]int)    scoreMap["张三"] = 90    scoreMap["小明"] = 100    // 如果key存在ok为true,v为对应的值;不存在ok为false,v为值类型的零值    v, ok := scoreMap["张三"]    if ok {        fmt.Println(v)    } else {        fmt.Println("查无此人")    }    //使用delete()函数删除键值对      delete(scoreMap, "小明")//将小明:100从map中删除

数组按照下标排序输出

    tetcc := make(map[int]string,5)    tetcc[1] = "smallsha"    tetcc[5] = "smallsha1"    tetcc[3] = "smallsha2"    sli := []int{}    for i := range tetcc {        sli = append(sli,i)    }    sort.Ints(sli)    for i := 0; i < len(tetcc); i++ {        fmt.Println("内容",tetcc[sli[i]])    }    fmt.Printf("%#v\n", sli)    return

if判断

    if test2 :=19; test2> 20 {        fmt.Println("test11212121212")    }else if test2 < 20 {        fmt.Println("test1111")    }

switch使用

    test3 := 80    switch test3 {    case 80:        fmt.Println("1")        fallthrough  //可以使用fallthrough强制执行后面的case代码。    case 90:        fmt.Println("2")    case 100:        fmt.Println("3")    default:        fmt.Println("default")    }

多个参数调用

   func test(s string, n ...int) string {    var x int    for _, i := range n {        x += i    }    return fmt.Sprintf(s, x)}     s := []int{1, 2, 3}    res := test("sum: %d", s...)    // slice... 展开slice    println(res)

闭包使用

func a() func() int  {    i := 0    b := func() int{        i++        fmt.Println(i)        return i    }    return b}    ccccc := a()    ccccc()    ccccc()    return

关键字 defer 用于注册延迟调用。

这些调用直到 return 前才被执。因此,可以用来做资源清理。

多个defer语句,按先进后出的方式执行

惯例是:导致关键流程出现不可修复性错误的使用 panic,其他使用 error。

func main() {    test()}func test() {    defer func() {        if err := recover(); err != nil {            println(err.(string)) // 将 interface{} 转型为具体类型。        }    }()    panic("panic error!")}

表达式

package mainimport "fmt"type User struct {    ID   int    name string}func (self *User) test() {    fmt.Printf("%p, %v\n", self, self)}func main() {    u := User{1, "Tom"}    u.test()    mValue := u.Test    mValue() // 隐式传递 receiver    mExpression := (*User).Test    mExpression(&u) // 显式传递 receiver}

定义error http://www.topgoer.com/%E6%96%B9%E6%B3%95/%E8%87%AA%E5%AE%9A%E4%B9%89error.html

//返回异常package mainimport (   "errors"   "fmt")func getCircleArea(radius float32) (area float32, err error) {   if radius < 0 {      // 构建个异常对象      err = errors.New("半径不能为负")      return   }   area = 3.14 * radius * radius   return}func main() {   area, err := getCircleArea(-5)   if err != nil {      fmt.Println(err)   } else {      fmt.Println(area)   }}//系统抛异常package mainimport "fmt"func test01() {   a := [5]int{0, 1, 2, 3, 4}   a[1] = 123   fmt.Println(a)   //a[10] = 11   index := 10   a[index] = 10   fmt.Println(a)}func getCircleArea(radius float32) (area float32) {   if radius < 0 {      // 自己抛      panic("半径不能为负")   }   return 3.14 * radius * radius}func test02() {   getCircleArea(-5)}//func test03() {   // 延时执行匿名函数   // 延时到何时?(1)程序正常结束   (2)发生异常时   defer func() {      // recover() 复活 恢复      // 会返回程序为什么挂了      if err := recover(); err != nil {         fmt.Println(err)      }   }()   getCircleArea(-5)   fmt.Println("这里有没有执行")}func test04()  {   test03()   fmt.Println("test04")}func main() {   test04()}//自定义errorpackage mainimport (    "fmt"    "os"    "time")type PathError struct {    path       string    op         string    createTime string    message    string}func (p *PathError) Error() string {    return fmt.Sprintf("path=%s \nop=%s \ncreateTime=%s \nmessage=%s", p.path,        p.op, p.createTime, p.message)}func Open(filename string) error {    file, err := os.Open(filename)    if err != nil {        return &PathError{            path:       filename,            op:         "read",            message:    err.Error(),            createTime: fmt.Sprintf("%v", time.Now()),        }    }    defer file.Close()    return nil}func main() {    err := Open("/Users/5lmh/Desktop/go/src/test.txt")    switch v := err.(type) {    case *PathError:        fmt.Println("get path error,", v)    default:    }}

interface 应用

// 空接口作为函数参数func show(a interface{}) {    fmt.Printf("type:%T value:%v\n", a, a)}// 空接口作为map值    var studentInfo = make(map[string]interface{})    studentInfo["name"] = "李白"    studentInfo["age"] = 18    studentInfo["marrIEd"] = false    fmt.Println(studentInfo)

go调度 sync.WaitGroup

var wg sync.WaitGroupfunc hello(i int) {    defer wg.Done() // goroutine结束就登记-1    fmt.Println("Hello Goroutine!", i)}func main() {    for i := 0; i < 10; i++ {        wg.Add(1) // 启动一个goroutine就登记+1        go hello(i)    }    wg.Wait() // 等待所有登记的goroutine都结束}

go runtime.Gosched()

//让出cpu时间片,重新等待安排任务(大概意思就是本来计划的好好的周末出去烧烤,但是你妈让你去相亲,两种情况第一就是你相亲速度非常快,见面就黄不耽误你继续烧烤,第二种情况就是你相亲速度特别慢,见面就是你侬我侬的,耽误了烧烤,但是还馋就是耽误了烧烤你还得去烧烤)package mainimport (    "fmt"    "runtime")func main() {    go func(s string) {        for i := 0; i < 2; i++ {            fmt.Println(s)        }    }("world")    // 主协程    for i := 0; i < 2; i++ {        // 切一下,再次分配任务        runtime.Gosched()        fmt.Println("hello")    }}

runtime.Goexit()

//退出当前协程(一边烧烤一边相亲,突然发现相亲对象太丑影响烧烤,果断让她滚蛋,然后也就没有然后了)package mainimport (    "fmt"    "runtime")func main() {    go func() {        defer fmt.Println("A.defer")        func() {            defer fmt.Println("B.defer")            // 结束协程            runtime.Goexit()            defer fmt.Println("C.defer")            fmt.Println("B")        }()        fmt.Println("A")    }()    for {    }}

runtime.GOMAXPROCS

//Go1.5版本之后,默认使用全部的cpu逻辑核心数///两个任务只有一个逻辑核心,此时是做完一个任务再做另一个任务。 将逻辑核心数设为2,此时两个任务并行执行,代码如下。func a() {    for i := 1; i < 10; i++ {        fmt.Println("A:", i)    }}func b() {    for i := 1; i < 10; i++ {        fmt.Println("B:", i)    }}func main() {    runtime.GOMAXPROCS(2)    go a()    go b()    time.Sleep(time.Second)}
通道

1.对一个关闭的通道再发送值就会导致panic。

2.对一个关闭的通道进行接收会一直获取值直到通道为空。

3.对一个关闭的并且没有值的通道执行接收 *** 作会得到对应类型的零值。

4.关闭一个已经关闭的通道会导致panic。

5.chan<- int是一个只能发送的通道,可以发送但是不能接收;

6 <-chan int是一个只能接收的通道,可以接收但是不能发送。

func counter(out chan<- int) {    for i := 0; i < 100; i++ {        out <- i    }    close(out)}func squarer(out chan<- int, in <-chan int) {    for i := range in {        out <- i * i    }    close(out)}func printer(in <-chan int) {    for i := range in {        fmt.Println(i)    }}func main() {    ch1 := make(chan int)    ch2 := make(chan int)    go counter(ch1)    go squarer(ch2, ch1)    printer(ch2)}
通道使用案例
type Job struct {    ID      int    RandNum int}type Result struct {    job *Job    sum int}func createPool(num int, jobChan chan *Job,resultChan chan *Result) {    for i := 0; i < num; i++ {        go func(jobChan chan *Job,resultChan chan *Result) {            for i2 := range jobChan {                r_num := i2.RandNum                var sum int                for r_num !=0 {                    tmp := r_num % 10                    sum += tmp                    r_num /= 10                }                r := &Result{                    job: i2,                    sum: sum,                }                resultChan <- r            }        }(jobChan,resultChan)    }}func main() {    flag.Parse()    jobChan := make(chan *Job, 128)    resultChan := make(chan *Result, 128)    createPool(64, jobChan, resultChan)    // 4.开个打印的协程    go func(resultChan chan *Result) {        // 遍历结果管道打印        for result := range resultChan {            fmt.Printf("job ID:%v randnum:%v result:%d\n", result.job.ID,                result.job.RandNum, result.sum)        }    }(resultChan)    var ID int    // 循环创建job,输入到管道    for {        ID++        // 生成随机数        r_num := rand.Int()        job := &Job{            ID:      ID,            RandNum: r_num,        }        jobChan <- job    }    return    }
select 监听通道
    select {    case <-chan1:       // 如果chan1成功读到数据,则进行该case处理语句    case chan2 <- 1:       // 如果成功向chan2写入数据,则进行该case处理语句    default:       // 如果上面都没有成功,则进入default处理流程    }
flag使用 和 os.args
   var name string    var age int    var marrIEd bool    var delay time.Duration    flag.StringVar(&name, "name", "张三", "姓名")    flag.Intvar(&age, "age", 18, "年龄")    flag.BoolVar(&marrIEd, "marrIEd", false, "婚否")    flag.DurationVar(&delay, "d", 0, "延迟的时间间隔")    或者使用    name := flag.String("name", "张三", "姓名")    age := flag.Int("age", 18, "年龄")    marrIEd := flag.Bool("marrIEd", false, "婚否")    delay := flag.Duration("d", 0, "时间间隔")    //解析命令行参数    flag.Parse()    fmt.Println(name, age, marrIEd, delay)    //返回命令行参数后的其他参数    fmt.Println(flag.Args())    //返回命令行参数后的其他参数个数    fmt.Println(flag.NArg())    //返回使用的命令行参数个数    fmt.Println(flag.NFlag())    //os.args        if len(os.Args) > 0 {        for index, arg := range os.Args {            fmt.Printf("args[%d]=%v\n", index, arg)        }    }
Log文件
    logfile, err := os.Openfile("./smallsha.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)    if err != nil {        fmt.Println("open log file Failed, err:", err)        return    }    log.Setoutput(logfile)  //设置日志文件写入    log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)    log.SetPrefix("[smallsha]")    log.Printf("%s","smallsha")    log.Println("test")    //log.Panic("test1")    //log.Fatalln("test2")    logger := log.New(os.Stdout, "<New>", log.Lshortfile|log.Ldate|log.Ltime)    logger.Println("这是自定义的logger记录的日志。")
循环 *** 作
arr := [5]int{1,2,4,5,6,8}for i,num :=range arr {    fmt.Println(i,num)}//while for 循环配合通道    var (        ch11 = make(chan int)        ch12 = make(chan int)    )    go func() {        for i := 0; i < 10; i++ {            ch11 <- i        }        close(ch11)    }()    go func() {        for {            i, ok := <-ch11            if !ok {                break            }            ch12 <- i * i        }        close(ch12)    }()    for i := range ch12 {         fmt.Println(i)    }
指针
const MAX int =3func main(){    a :=[]int{1,3,5}    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] )   }}
strconv 使用
    s3, _ := strconv.ParseBool("1")    fmt.Printf("%# v\n", pretty.Formatter(s3))    return    //int 转 string    s2 := 100    i2 := strconv.Itoa(s2)    fmt.Printf("%# v\n", pretty.Formatter(i2))    return    //string 转 int    s1 := "100"    i1, err := strconv.Atoi(s1)    if err != nil {        fmt.Println(err)        return    }    fmt.Printf("%# v\n", pretty.Formatter(i1))    return
template使用可以注册http
package logicimport (    "fmt"    "HTML/template"    "net/http")func init() {    http.HandleFunc("/",sayHello)    err := http.ListenAndServe(":9090", nil)    if err != nil {        fmt.Println(err)        return    }}type UserInfo struct {    name   string    Gender string    Age    int}func sayHello(w http.ResponseWriter,r *http.Request)  {    // 解析指定文件生成模板对象    tmpl, err := template.Parsefiles("./hello.HTML")    if err != nil {        fmt.Println("create template Failed, err:", err)        return    }    // 利用给定数据渲染模板,并将结果写入w    user := UserInfo{        name:   "枯藤",        Gender: "男",        Age:    18,    }    // 利用给定数据渲染模板,并将结果写入w    tmpl.Execute(w, user)}
定义结构体
package mainimport "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)}//结构体new 和赋值 type Person struct {    Username string `Json:"username"`    Password string `Json:"password"`}//声明构造方法func newPerson(username string, password string) *Person {    return &Person{        Username: username,        Password: password,    }}//定义修改结构体的方法func (p *Person) setUsername(username string) {    p.Username = username}
map *** 作
package mainimport "fmt"func main() {    var countryCAPItalMap map[string]string /*创建集合 */    countryCAPItalMap = make(map[string]string)    /* map插入key - value对,各个国家对应的首都 */    countryCAPItalMap [ "France" ] = "巴黎"    countryCAPItalMap [ "Italy" ] = "罗马"    countryCAPItalMap [ "Japan" ] = "东京"    countryCAPItalMap [ "India " ] = "新德里"    /*使用键输出地图值 */    for country := range countryCAPItalMap {        fmt.Println(country, "首都是", countryCAPItalMap [country])    }    /*查看元素在集合中是否存在 */    cAPItal, ok := countryCAPItalMap [ "American" ]    /*删除元素*/ delete(countryCAPItalMap, "France")    /*如果确定是真实的,则存在,否则不存在 */    /*fmt.Println(cAPItal) */    /*fmt.Println(ok) */    if (ok) {        fmt.Println("American 的首都是", cAPItal)    } else {        fmt.Println("American 的首都不存在")    }}
声明变量    package main    import "fmt"    func main() {        var a string = "Runoob"        fmt.Println(a)        var b, c int = 1, 2        fmt.Println(b, c)    }声明方法    package main    import "fmt"    func swap(x, y string) (string, string) {       return y, x    }    func main() {       a, b := swap("Google", "Runoob")       fmt.Println(a, b)    }定义数组    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}    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 mainimport "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)    }
声明函数和方法区别
#函数func main() {    sum := add(1, 2)    fmt.Println(sum)}func add(a, b int) int {    return a + b}#方法type person struct {    name string}func (p person) String() string{    return "the person name is "+p.name}func main() {    p:=person{name:"张三"}    fmt.Println(p.String())}#可变参数func main() {    print("1","2","3")}func print (a ...interface{}){    for _,v:=range a{        fmt.Print(v)    }    fmt.Println()}
修改字符串 需要先转换成 byte 或者 rune
func changeString() {    s1 := "hello"    // 强制类型转换    byteS1 := []byte(s1)    byteS1[0] = 'H'    fmt.Println(string(byteS1))    s2 := "博客"    runes2 := []rune(s2)    runes2[0] = '狗'    fmt.Println(string(runes2))}
总结

以上是内存溢出为你收集整理的GO 语言快速学习 | PHP转GO笔记全部内容,希望文章能够帮你解决GO 语言快速学习 | PHP转GO笔记所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1001282.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存