6

【go系列2】 关于go中与java C++中应该注意的语法糖以及不同点

 3 years ago
source link: https://segmentfault.com/a/1190000038298029
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

背景

最近在用golang写k8s operator(其中涉及到informer controler )用于内部调度平台用,刚好借此机会能够与java版本的 informer controller 进行对比,由于之前对golang没怎么接触过,遇到了和java c++不同的语法糖,现在列举一下:

具体不同

golang中struct

golang中没有class的概念,但是有struct,而且可以给struct增加方法,如下:

type Member struct {
    Id     int    `json:"id"`
}
//绑定到Member结构的方法,但是这种不会改变member的值,因为结构体是值传递,当我们调用setID时,方法接收器接收到是只是结构体变量的一个副本,通过副本对值进行修复,并不会影响调用者,因此,我们可以将方法接收器定义为指针变量,就可达到修改结构体的目的
func (m Member)setId(id int){
    m.Id = id
}
m := Member{}
m.setId(1)
fmt.Println(m.Id)//输出为空
//绑定到Member结构的方法,会改变member的值 
func (m *Member)setId(id int){
    m.Id = id
}
m := Member{}
m.setId(1)
fmt.Println(m.Id)//输出为1

关于方法的接受者和接口如何被调用,参考如下:

  • 不管方法的接收者是值还是指针,对象的值和指针均可以调用该方法型,那么方法的接受者可以是值类型也可以是指针类型
  • 当方法的接收者是值时,不管是值调用还是指针调用,方法内部都是对原对象的副本进行操作,不会影响原对象型,那么方法的接受者必须也是值类型该方法才可以被调用
  • 当方法的接收者是指针时,不管是值调用还是指针调用,方法内部都是通过指针对原对象进行操作,会影响原对象

定义struct的tags

在定义strut的结构体时,可以添加tag,tag可以在运行时用到,以及形成json或者xml时用到如下:

type NetworkList struct {
    Project  `json:",inline"`
    f2 int    `json:"id,-"`
    f3 string `json:"f3,omitempty"`
    f4 string `json:"f4"`
}

type Project struct {
    Key   string `json:"key"`
    Value string `json:"value"`
}

其中,

名词 解释 json:",inline" 表示内嵌类型的key和外层struct的key是平行关系,如NetworkList里的key和Project key在形成json的时候是平行关系,不是内嵌关系,也就是在同一级 json:"id,-" -(横杠) 表示私有字段,形成json的时候不包括该key json:"f3,omitempty omitempty表示该字段为空,则生成json时,不包括该key json:"f4" 表示生成json时,key为f4

golang的类型转换

c++ java 中有隐式类型转换,golang没有,golang中有强制类型转换和类型断言

  • 强制类型转换
package main

import "fmt"

func main() {
    var a float32 = 5.6
    var b int = 10
    fmt.Println (a * float32(b))
}
  • 类型断言
package main

import "fmt"

func main() {
    var a interface{} =10
    t,ok:= a.(int)
    if ok{
        fmt.Println("int",t)
    }
    t2,ok:= a.(float32)
    if ok{
        fmt.Println("float32",t2)
    }
}

golang中的interface{}

interface{}是空接口没有任何方法,且所有类型都实现了空接口,相当于java中的object,interface类型默认是一个指针

golang中的go关键字

go 关键字用来创建 goroutine (协程),是实现并发的关键

//go 关键字放在方法调用前新建一个 goroutine 并让他执行方法体
go GetThingDone(param1, param2);

//上例的变种,新建一个匿名方法并执行
go func(param1, param2) {
}(val1, val2)

//直接新建一个 goroutine 并在 goroutine 中执行代码块
go {
    //do someting...
}

golang中的defer关键字

  • defer 的执行方式类似其他语言中的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个执行
  • 即使函数发生严重错误也会执行,相当于finally
  • 常用于资源清理、文件关闭、解锁以及记录时间等操作
func main() {
  fmt.Println("a")
  
  defer fmt.Println("b")
  defer fmt.Println("c")
}
//打印
//a
//c
//b

golang中的init 函数

golang的init函数在该文件被被引用时才执行(是import时,不是调用包函数时)

package lib
import "fmt"
func init() {
    fmt.Println("lib empty init ")
}
----
package main

import (
    "Test/lib"
    "fmt"
)

func main() {
    fmt.Println("wint")
}
// 输出
//lib empty init  
//wint

匿名函数

该用法和java C++中差不多

func() {
    //func body
}()     //花括号后加()表示函数调用,此处声明时为指定参数列表,
        //故调用执行时也不需要传参

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK