chaofx

go 语言的学习和整理
爆肝一个月学习的go基础的 整理一下前言为什么我要学习go语言,原因大致也就是下面几个。|´・ω・)ノ早在2年前就...
扫描右侧二维码阅读全文
30
2020/07

go 语言的学习和整理

爆肝一个月学习的go基础的 整理一下

前言

为什么我要学习go语言,原因大致也就是下面几个。|´・ω・)ノ

  • 早在2年前就想学习,奈何自己挤不出时间,因为go语言是最萌的语言
  • 个人看好go在未来的发展,执行效率和并发上面都是有天然的优势
  • 想学习其他的编程语言,通过不同编程思想来更好的理解java

其实还是想学就学,没有什么过多纠结的。那我就开始来梳理一下最近学习的go语言和并且与java进行对比 梳理 【可能是java学习go的福音文章


简单介绍一下基础信息

go是一门强类型的编程语言(比java弱),在编写go的时候 也是存在oop的思想,但也会看到js的func影子,也会看到Python的类类似语法。go 代码规范要求高,连方法大小写,括号,缩进都规定了 变得是非常的简洁【<u>不会产生没有用到的代码</u>】。还有有天然的协程并发优势,多线程开发或许会爱不释手。


helloWorld

开局helloWorld不解释

import fmt //相当于java的System包
func main(){ //主入口 main函数
   fmt.Print("helloWorld")
}

基本数据类型 = 结构体+数组+基本字段

基本字段解释和一些关键词

go的基本字段类型

//go
int 
uint
float 
bool
string 

你没有看错,基本数据类型 就只有五种类型,没有像java那样字符集的字段分为 byte short long int,以int64表示为long

字段的声明方式

var param_name type
var param_name = value
var param_anme := value

如果你熟悉js看见这个var[关键词] 想必不陌生,go可以定义值的对象 或者进行类型推导定义。

var number int;//声明一个int 的number变量 普通声明
var number2 = 20 //推断声明一个number2 为20的变量
number3 := 30 //简单声明一个类型对象 就是把:代替了var
number = 10

var a,b,c int;
a=1
b=2
c=3
var a1,b2,c3 = 4,5,"eat";

//声明列表
var (
    z = 2
    x = "go"
)

const 【关键字】

简意:常量 在运行的时候不能修改 (相当于java 的final 在顶部修饰的不可变常量)
字母都要大写下划线分开

const var NORMAL_PARAM = 10 //声明方式不能用简单声明的方式。a:=10这种

iota 【关键字】

一个程序计数器,搭配const使用,相当于一个const里面的下标指针,当下一个const出现就会被重置

这个东西好像没有啥用,先写着吧

const(){
    a = iota iota 的 值 = 0,
    b = 1, iota 的 值 =1
}

关系运算符

》 > < >= <= != 和java一样

位运算关系符

增加一个位清空的概念
&^:位清空 a&^b
针对于b来说。如果b上值0则取a对应的值。b上位1则取0


条件语句

if
if 条件 
  逻辑
else
 逻辑
//在go语法。if可以增加一个条件 
if num1:=2 ; num1 >= 3 {
    f.Print("这个 num1的 作用范围就是在 if语句里面")
}
 

注意点就是 if了可以增加一个 当前的 暂时条件 存在于if判断结束 相当于在java的for 里面 int i = 1


switch 【关键字】

switch 用起来来和java差不多 最大一点就是不用加break
跟if一样 可以额外增加方法内的条件 switch 条件;type{}
还有一点很重要 case支持多条件 case a,b,c
如果swtich不写 type 那就是默认bool的值,可以早case里面写条件判断了

falltrough 【关键字】

可以穿透到下一个case里面去 不需要判断就行执行了,大多数语言都是默认穿透的

num:= 2
switch num {
    case 2:
        f.Print("这是一个2")
    case 3:
        f.Print("这是一个3")
        fallthrough //穿透
    case 4://上面有穿透这个 4就不需要判断就可以进来了 
       f.print("这是一个4“)
    default:
        f.Print("着啥也不是")
}

swtich word := "A" ; word{
    case "A", "E","i","O","u":
       fmt.println("这是一个元音字母")
    case "B","s"
       fmt.println("这是一个其他字母")
} 

for【关键字】

表达式:for 变量;条件;变量修改 {

}

//写法一
for i:=1;i<= 4;i++{

}
//写法二 支持这么写
i:=1
for i<=4 {
   
  i++  
}
// 写法三 相当于 while(true)
for {
    //死循环
}

break和continue

和java一样


数组

数组是基本数据类型,在方法值传递的时候 拷贝了一份数据过去,不会因为在其他方法体中改变了数据 而改变主体方法的数据,切片才是对于java的数组

声明方式

  1. var name [num] type
  2. var name = [num] type {value,value}
  3. name:=[...] type{value,value}

cap(array) //获取数组的容器的大小
len(array) //获取数据存储变量长度

数组一种特殊的循环

这个在循环的时候 可以取到index 和java只能依靠下标或者遍历循环 更加;灵活的一点

for index,value := range array_name{
    //index 下标
    //value 值
}
//不想接受index值就写成for _,value ····

结构体 struct

【是值类型的传递,*struct才是有对象的概念】

表达式:type struc_name struct

type Person struct {
    name string
    age int
    canEat bool
}
func strucuse()  {
    var person1 Person
    person1.name = "小埋"
    person1.age = 15
    person1.canEat = true
    f.Println(person1)

    var person2  = Person{"jb",2,true}
    f.Println(person2)

    var person3  = Person{name:"我的", age:12,canEat: true}
    f.Println(person3)
}

oop思想

结构的体的oop思想
在struct里面加入的了其他的结构体 相当于继承了,可以进行简写

 type person strcut{
    name string 
    age int
}
type man strcut{
    name string 
    person
}

func main() {
   man := man{}
   man.age = 12
   man.name = "22"
   man.person.name = ”出现相同字段 要点出那个对象 在赋值“
}

复合数据类型 = 切片+map+指针

切片

切片大致就是java的list,是一个引用类型的数据

声明一个切片,跟声明一个数组差不多,但是不要在[]中加入局的数字,不加为切片 加为数组,go语言在这个设计上真的是很简约,以manke内置函数创建make(type,存储的大小,容器的大小),超过容器的长度会自动扩容,增加一个

  1. var name [] type
  2. make(type,储存的大小,容器的大小)
增加一个值的内容(扩容)

name := apppend([]type,value ...) //value可以是多个 也可以是一个切片

var slice [] int
var slice2 [] int
temp := append(slice, 1,2)
temp2 := append(slice, slice2...)

go 没有改变原始slice对象的内存引用地址,所有经过拷贝后增加,然后创建了一个新对象去接收。


map

map是一个键值对,这还是和java差不多的

声明方式:var map_name map[key_type]value_type

  1. var map1 map[int]string
  2. make(map[int]string)
  3. var map1 = map[int]string{1:"22"}

第一种创建没有复制这个map是一个nil(null)相当于null,make函数就是把这个对象初始化了但是没有赋值!!!

增加map的keyvalue

这个map必须是被实例化过的 就是make过的或者 初始化赋值过的
map[key] = value

删除map的value

delete(map_name,key)

获取值

value,ok=map[key]

ok 用来时判断是否获取到这个值,因为go 通过key获取值 如果没有该键也会返回该map默认的value类型的值

map循环

表达式 for key,value := range map_name{
}


指针

指针是一个储存一个对象的内存地址的复合类型
表达式:T (T代表任何类型 如果是想存指针那就是*pointer)

var a = 1
s := &a //就是指针
ss := &a 
fmt.Print(*s)
fmt.Print(**ss)

其他一些基础关键知识

defer

延迟执行函数

可以让某一行 代码在这个方法体结束的时候结束,如果有多defer修饰
那么是以先进后出的方式执行

func main(){

    var s = "a"
    var num = 1

    defer fmt.Print(s)
    
    defer fmt.Print("这个比上面那个先执行")
    
    defer Print(num) 
    
    num++
      
    fmt.Print("这是结束的")
}

func Print(a int){
  fmt.Print(a)//这里打印出来时1 不会因为num++变成2 ,可以   理解成法法已经装载好了,但是还没有执行Q!。如果是复合数据类型就会改变
}

defer像finnaly一样处理 关闭流程 或者处理错误之类的

回调函数

func main(){
 aa := B( 1,2, func(){2,1})
}  
func B(a, b int, method_name func(c,d int))int{
  return a-b-c-d
}

闭包结构

大概:内层函数调用了外层函数的局部变量,导致外层函数的那个变量生命周期改变,变量内存的逃逸。

每一个方法被调用 就会有一个地址内存地址,。方法就是对象!!!

func main(){
   res := method()
   ftm.Print(res()) //1 res这个方法中i的内存地址指向的是method被调用的那个地址,
   ftm.Print(res()) //2
   ftm.Print(res()) //3
}

f  unc method() func()int{
    i := 0
   return func () int{
      i++
      return i  
    }
}

error 是一个错误类型

在errors包下面可以去 新建一个错误类型做为函数判断返回
errors.New("这是一个错误的类型"),
或者说是fmt.Error("这是一个错误类型")

panic recover

panic 抛出异常 -------- java try
recover 恢复异常 ----- java catch

painc(a intterface{}) ..可以放入参数 让recover接收
painc的代码都不会去执行 先当于当前return了,之前的defer的代码也是要被执行的额

recover 恢复恐慌 可以接收painc传过来的参数

接口

go以面定义的一个接口的话,只要方法实现了该接口的所有方法,那么这个方法就是实现了这个接口,不需要去指派哪struct实现了哪个接口
非侵入式的

type Phone interface {
    call()
}
type NokiaPhone struct {
}
func (nokiaPhone NokiaPhone) call() {
    fmt.Println("I am Nokia, I can call you!")
}
type IPhone struct {
}
func (iPhone IPhone) call() {
    fmt.Println("I am iPhone, I can call you!")
}
func main() {
    var phone Phone
    phone = new(NokiaPhone)
    phone.call()
    phone = new(IPhone)
    phone.call()
}

两部手机都实现了phone的call方法,通过接口模拟实现了多肽,可以把struct 的值赋值给接口 ,然后在调用phone Pohone = new (Iphone),Phone等于父类

空接口

任何东西都可以可以多肽化,相当于java object对象

接口继承

在接口里面写其他接口,如果要实现这个接口,就要实现这个接口及其父接口的所有方法

版权属于:本文为原创文章,版权归本博所有,转载请注明出处!。

如果文章 语句 文字 描述等有错误 只能请在座的各位多多包涵 博主说话没有切格瓦拉好听。

感谢您本次的阅读

Last modification:July 31st, 2020 at 01:27 am
If you think my article is useful to you, please feel free to appreciate

Leave a Comment

隐藏