Java 转 Go 之初体验

点击上方“Java基基”,选择“设为星标”

做积极的人,而不是积极废人!

每天 14:00 更新文章,每天掉亿点点头发...

源码精品专栏

 

来源:blog.csdn.net/tiantang_zy/

article/details/105048817


面试了一个单位 说可能需要java转go语言 所以在此开始学习一下 如果面试通过了就继续学 没面试过 那么就这一篇了 加油!!!

01、万能之Hello World 开启go的大门

直接上代码

package main //表明包

import "fmt" //导入包 fmt 控制输入输出 感觉和java的System.out和Scanner有点像

func main() {
    fmt.Println("Hello Go world。"); //进入这个世界了
}

输出结果:

d0a81dca5e4c1107957fc937576d61fd.png

是不是感觉还可以。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。

项目地址:https://github.com/YunaiV/ruoyi-vue-pro

02、Go语言环境安装

安装包下载地址为:https://golang.org/dl/。

如果打不开可以使用这个地址:https://golang.google.cn/dl/。

0c7e1c681e2f7efe7893ae8916c4a971.png

我安装的是windows版的 双击安装选择目录 全程轻松随意 比想象中简单

bab44d1f2c1446f9fcef6ed5f216b571.png配置系统变量,然后就可以开始玩了

470bd60484069df3cf10aa9ee9fbbb03.png

基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。

项目地址:https://github.com/YunaiV/onemall

03、基础语法

  • 行分割符:不需要像java一眼每句之后都加一个;表明结束 每一行都是单独的一句 如果非要把几行语句写在一起 就需要加分号了

  • 注释 : //单行注释 /* aaa bbb */

  • 标识符 标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(AZ和az)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。

  • 字符串连接 直接用+号即可连接 这点倒是和java挺像的 但是java里直接用加号连接的性能不是很好 不知道go语言中是否有相类似的编译流程

  • 关键字

    03292bdbae0fba18e64961309d31ca01.png
  • 预定义标识符

    ef6f35e5994c68dcdb0454ec381e6bba.png

04、数据类型

046cf61f474bbe8e6ce9d7192fb802f9.png数据类型详细的可以看这个:https://www.runoob.com/go/go-data-types.html 首先一点,给我印象比较深的就是 对数字类型添加了很多的包装,在不同的应用范围内使用不同的数据类型 例如

  • int8 有符号 8 位整型 (-128 到 127)

  • int16 有符号 16 位整型 (-32768 到 32767)

  • int32 有符号 32 位整型 (-2147483648 到 2147483647)

  • int64 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807) 这个给人感觉就是对使用着感觉 有了更高的要求 像java就是int Integer BigInteger这几种包装好的用就行了 当然这样要求的更细致 感觉编译的时候 就越容易控制 如果方方面面都这么细致的话 运行速度上就可以提高不少的

05、声明变量

  1. var identifier type 例:var a int;

  2. var identifier1,identifier2 type 例:var a,b string;

  3. 指定变量类型,如果没有初始化,则变量默认为零值 数值类型(包括complex64/128)为 0 布尔类型为 false 字符串为 “”(空字符串) 以下几种类型为 nil:var a *int var a []int var a map[string] int var a chan int var a func(string) int var a error // error 是接口

  4. 根据值自行判定变量类型 例:var d = true (这点就有点像js了)

  5. 省略 var, 注意 := 左侧如果没有声明新的变量,就产生编译错误,格式:v_name := value 例:f := “Runoob”

  6. 多变量声明

//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3

// 和 python 很像,不需要显示声明类型,自动推断
var vname1, vname2, vname3 = v1, v2, v3 

// 出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误
vname1, vname2, vname3 := v1, v2, v3 


// 这种因式分解关键字的写法一般用于声明全局变量
var (
    vname1 v_type1
    vname2 v_type2
)

06、常量

const 定义常量关键字 目前感觉和final static 类似 定义了之后就不能改了 如果代码里面改了的话 会报 cannot assign to LENGTH 错误

b247b5d1751d9191b440b73acb457e41.png

下来就发现一个神奇懂东西 iota iota,特殊常量,可以认为是一个可以被编译器修改的常量。

iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。

e9312c8d875c0ab140ae6a726719918c.png

枚举自增计数器 感觉是这么个意思

07、运算符

26d9b87a5a061d378f4fa3f6c5c4a0ee.png d76252acb9db785f27783ce75a2338e1.png c9d151181898c2bf200fe6108aab79e5.png e180cf441ac7c1b87acd9f0d159d8bbd.png

&这个就是只有两个1的时候才是1其余都是0 |这个是只有两个0的时候才是0其余都是1和与刚好相反 ^这个简单粗暴两个相同的数字是0不同的时候是1

4b2b81dd259f5e6da78016ecc29f7fc4.png f9f36e6aba5651d5bc6fbbba3b08ab0b.png

这个<<=后面的几个都还有点惊艳到我了 厉害厉害

b3ede5d8a03cdb977cb80c286e79474c.png

这两个优点没太看懂 敲个代码试一下

package main

import "fmt"

func main(){
 var a string = "abc"
 var ptr *string = &a
 fmt.Printf("第 1 行 - a 变量类型为 = %T\n", a );
 fmt.Printf("第 2 行 - ptr  变量类型为 = %T\n", ptr );
 fmt.Println(*ptr)
 fmt.Println(ptr)
}
789e9fcfaaa44cc85113fe0ca6461f07.png

加*输出的是内容 不加输出的就是地址 这个指针的概念 java里是没有的

06bab1bc4da153f86ee25861b300a49e.png

这一part 感觉除了指针的概念 其余的感觉都差不多 详细例子:https://www.runoob.com/go/go-constants.html

08、条件语句

fbcb6828093d1263f67e41d457e382ff.png

这个select语句真的是看的我欲生欲死 以下描述了 select 语句的语法:

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

来来来 两段代码说明一下

package main

import (
    "fmt"
)

func fibonacci(c, quit chan int) {
    x, y := 1, 1
 
    for {
        select {
        case c <- x:
      fmt.Printf("x : %d, y : %d\n", x, y)
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    c := make(chan int)
    quit := make(chan int)

    go func() {
        for i := 0; i < 6; i++ {
      fmt.Printf("开始搞事 i = %d\n", i)
            fmt.Println(<-c)
        }
        quit <- 0
    }()

    fibonacci(c, quit)
}

输出结果为:

fd72547eda80bf7f79f8474a1c7ac4cb.png

第二段代码:

package main

import (
    "fmt"
    "time"
)

func Chann(ch chan int, stopCh chan bool) {
    for j := 0; j < 10; j++ {
        ch <- j
        time.Sleep(time.Second)
    }
    stopCh <- true
}

func main() {

    ch := make(chan int)
    c := 0
    stopCh := make(chan bool)

    go Chann(ch, stopCh)

    for {
        select {
        case c = <-ch:
            fmt.Println("Recvice", c)
            fmt.Println("channel")
        case s := <-ch:
            fmt.Println("Receivessss", s)
        case _ = <-stopCh:
            goto end
        }
    }
end:
}

输出结果为:

985e7728ee5d35f4b51b58ab3c5383a3.png

这两个例子分别说明了下面两点 如果任意某个通信可以进行,它就执行,其他被忽略。如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。

但是有个疑问 为啥第一个例子里在执行偶数次的时候 xy会交换两次 在下一次调用的时候又不会进行交换?内部是怎么实现的???真想打个断点调试一下 这个问题如果我往后会做go的话 我一定会回来的!!!!

今天就学到这里了



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

02905d532432cfd9c83b7dd04f0ec9d9.png

已在知识星球更新源码解析如下:

5916055a811bbaeb685af0a9c05298e4.png

c14cdf413d3572746f12535b6e93c904.png

a60bbad68cc25c2ce9fe504551135584.png

c5194de5ea5c9ea184b2095ed6ea4355.png

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值