Golang作为Docker、Kubernetes和OpenShift等一些酷辣新技术的首选编程语言,越来越受欢迎。尤其它们都是开源的,很多情况下,开源是非常有价值的。深入学习阅Golang等源代码库中的源文件,可以更深地理解它们,同时也有利于其他编程语言的开发者快速映射某些概念,比如Go与Java中常用概念的映射。本文的目的是帮助Java开发人员快速理解一些常见的Go习惯用法。

项目结构

Golang项目的一个常见约定是将所有cli二进制源文件或“main”包中的源文件放在根目录cmd文件夹下。通常可以在源根目录的pkg文件夹中找到实现了不同功能的内聚类型、常量、变量和函数集的包。

 

Golang将其代码组织成包,类似于Java。通过在源文件的顶部引入package来声明源文件所在的包(以及它的所有常量、类型、函数等)。但是与Java不同,不需要输入完整的包名+类名的路径,只需要输入包名即可。例如:

package api

假设有一个包“api/endpoint”,那么文件系统上就会有这个目录结构(例如:/pkg/api/endpoint),但是endpoint包在endpoint目录下的源文件中的声明,应该是这样的:

package endpoints

导入包

使用以下命令可以在程序中导入包,就像在Java中一样:

import (

stderrs "errors"

"time"

"Golang.org/x/net/context"

"k8s.io/kubernetes/pkg/auth/user"

)

可以根据包路径中的最后一个包名在源代码中使用包。例如,在上面的例子中,我们导入k8s.io/kubernetes/pkg/auth/user,通过代码,可以用user.Foo()引用包中的元素。同样也可以在源文件中重命名包,这样它就不会与其他包名发生冲突,就像上面例子里所示:

import (

stderrs "errors"

)

并在自己的程序源码中直接引用stderrs.Foo()。

Main包

main包是Golang应用程序的入口点。main包必须有一个main()函数,该函数不接受参数,也不提供返回值。例如:

func main() { … }

如前所述,这个包通常位于根目录的cmd文件夹中。

类型、常量、函数的作用域/可见性

在Golang中,对于结构/类型/函数/变量在包外部的作用域和可见性,其标识符的首字符非常重要。例如,在一个foo包中,如果有一个名为func Bar()的函数,那么因为“Bar”的第一个字母是大写的,所以它在包之外是可用的(注:类似于java中的public)。因此,如果导入了foo包,就能够调用foo.Bar()函数。如果“bar”是小写的,它将被隐藏起来(类似于java中的private)。也就是说,第一个字母的大小写决定了其作用域与可见性。

方法可以返回多个值

Golang中的函数或方法(两者有区别)可以返回“元组”或多个值,与java有明显差异。例如,调用一个返回多个值的函数如下所示:

internalCtx, ok := foo.bar(context.Context)

其中,internalCtx表示函数内容,ok可表示函数调用成功或失败标识。

类、结构、方法

在Java中有类,但在Go中与之相似的概念是结构体(Struct)。struct也可以有成员和方法。如下所示:

type Rectangle struct {

width int

height int

}

这是一个名为“Rectangle”的数据结构,它有两个成员变量(也可以称为字段,原文中为fields):宽度和高度。可以像这样创建实例:

r := new(Rectangle)

还可以这样引用它的成员变量(fields):

r.width = 10

r.height = 5

我们可以在“Rectangle”数据结构上编写方法,如下所示:

func (r *Rectangle) area() int {

return r.width * r.height

}

这里的方法名称为area,可以这么来调用上面的方法:

r := new(Rectangle)

r.area()

类型继承

Golang在设计上未采用Java的“继承(extends)”,它的继承是通过组合来完成的。例如:

type Rectangle struct {

Shape

width int

height int

}

上面Rectangle结构中有一个类型为Shape的匿名成员。Shape中包含的所有字段和方法在Rectangle对象上都是可见的。但是需要注意的是,不像在Java中,可以将Rectangle传递给Shape为参数的函数,这在Go中是行不通的。要获得这种类型的多态性,应该使用Go接口。

多态性、接口

在Java中有特定的接口类型,这些接口类型定义了对象的行为。在Go中,也有类似的概念,可以通过intefaces来实现。例如,下面这个接口声明了一个具有Print()方法的Shape类型:

type Shape interface {

Print()

}

当使用Go来创建结构时,不需要像在Java中那样用“implementation”来声明它。它是隐式的,只需要实现了该接口对应的方法,对应的结构体就可以被传递给需要的函数:

type Rectangle struct {

width int

height int

}

func (r *Rectangle) Print() {

fmt.println("Rectangle!");

}

此时,Rectangle对象可以传递给任何接收Shape类型的函数,因为它实现了该类型的所有方法。

For循环

Go中的For循环,样例如下:

for i := 1; i <= 10; i++ {

fmt.Println(i)

}

然而,当迭代一个数组(或类似于数组的东西,例如,字符串,映射,切片等),可以使用range运算符(假设foo是一个列表List):

for v := range foo {

fmt.println("value="+v);

}

如果在遍历列表时需要知道该列表的索引,则可以这样编写代码:

for i, v := range foo {

fmt.println("index " + i +"has value="+v);

}

While循环

Go中还可以像这样再次使用for循环:

sum := 1

for sum < 1000 {

sum += sum

}

fmt.Println(sum)

或者实现一个无限while循环:

for {

something...

}

指针和引用

Golang中需要显式地使用指针和引用,而Java通常隐藏这些。例如,Java中可以这样做:

Shape shape = new Shape();

shape.foo();

但是在Go中,必须直接处理指针

type Rectangle struct {

width int

height int

}

func updateRectangle(r *Rectangle){

r.width = 5;

r.height = 10;

}

func main() {

r := Rectangle{20,30}

updateRectangle(&r)

}

当main函数执行完毕时,Rectangle对象中r.width=5,r.height=10。注意:必须显式地引用指针。

 

垃圾回收机制

Golang与java类似,也是一种垃圾收集语言。Go开发者不需要手动来释放程序中不再使用的变量和结构占用的内存,在Go的运行时中有一个独立的进程,即垃圾收集器(GC),会处理这些事,它会通过标记算法搜索不再使用的变量然后释放内存。

通过调用runtime.GC()函数可以显式的触发GC,但这只在某些特殊的场景下才会使用,比如当内存资源不足时调用runtime.GC(),它会在此函数执行的点上立即释放内存,此时程序可能会有短时的性能下降(由于GC进程的执行)。如果想知道当前的内存状态,也可以使用如下代码:

var mruntime.MemStats

runtime.ReadMemStats(&m)

fmt.Printf("%dKb\n", m.Alloc / 1024)

上面的程序会给出已分配内存的总量,单位是 Kb。

原文作者:Christian Posta  译者:江玮

原文链接:https://dzone.com/articles/quick-go-lang-for-java-developers

版权声明:本文版权归作者(译者)及公众号所有,欢迎转载,但未经作者(译者)同意必须保留此段声明,且在文章页面明显位置给出,本文链接如有问题,可留言咨询。

JAVA开发者的Golang快速指南的更多相关文章

  1. 【SFA官方翻译】使用 Kubernetes、Spring Boot 2.0 和 Docker 的微服务快速指南

    [SFA官方翻译]使用 Kubernetes.Spring Boot 2.0 和 Docker 的微服务快速指南 原创: Darren Luo SpringForAll社区 今天 原文链接:https ...

  2. [译] MongoDB Java异步驱动快速指南

    导读 mongodb-java-driver是mongodb的Java驱动项目. 本文是对MongoDB-java-driver官方文档 MongoDB Async Driver Quick Tour ...

  3. Java程序员的Golang入门指南(下)

    Java程序员的Golang入门指南(下) 4.高级特性 上面介绍的只是Golang的基本语法和特性,尽管像控制语句的条件不用圆括号.函数多返回值.switch-case默认break.函数闭包.集合 ...

  4. Java程序员的Golang入门指南(上)

    Java程序员的Golang入门指南 1.序言 Golang作为一门出身名门望族的编程语言新星,像豆瓣的Redis平台Codis.类Evernote的云笔记leanote等. 1.1 为什么要学习 如 ...

  5. MessagePack Java 0.6.X 快速开始指南 - 安装

    0.6.x 版本的 MessagePack 已经过期被淘汰了.如果你现在开始使用 MessagePack 话,请不要使用这个版本. 我们再这里保留 0.6.x 版本的内容主要用于参考用途. 最新的 M ...

  6. java开发者最常去的20个英文网站

    java开发者最常去的20个英文网站: 1.[http://www.javaalmanac.com] Java开发者年鉴一书的在线版本. 要想快速查到某种Java技巧的用法及示例代码, 这是一个不错的 ...

  7. 从 C++ 到 Objective-C 的快速指南

    简介 当我开始为iOS写代码的时候,我意识到,作为一个C++开发者,我必须花费更多的时间来弄清楚Objective-C中怪异的东西.这就是一个帮助C++专家的快速指南,能够使他们快速的掌握Apple的 ...

  8. Java开发者想尝试转行大数据,学习方向建议?

      ​前言 相信很多Java开发者都对大数据有一定的了解,随着大数据时代的到来,也有很多Java程序员想要转行大数据.大数据技术中大多数平台使用的都是Java语言,因此,对于大数据技术的学习来说,Ja ...

  9. 100个高质量Java开发者博客

    ImportNew注:原文中还没有100个.作者希望大家一起来推荐高质量的Java开发博客,然后不段补充到这个列表.欢迎你也参与推荐优质的Java开发博客.(声明一下:我们的数学不是体育老师教的!:) ...

随机推荐

  1. Eigen使用矩阵作为函数参数

    1 使用矩阵作为函数参数介绍 文章来源Writing Functions Taking %Eigen Types as Parameters Eigen为了在函数中传递不同的类型使用了表达式模板技术. ...

  2. arguments.callee的作用及替换方案

    arguments.callee的作用 arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,返回正被执行的 Function 对象,也就是所指定的 Funct ...

  3. VC 中引用js文件

    #include "comutil.h" using namespace MSScriptControl; #include <MsHTML.h> #include & ...

  4. 分布式协议学习笔记(三) Raft 选举自编写代码练习

    由于时间安排上的原因,这次的代码写的稍微有些简略,只能算是自己对RAFT协议的一个巩固. 实现定义2个节点,使用读取配置文件来获取IP和端口以及节点ID 网络使用boost同步流程 一个线程收 一个线 ...

  5. springmvc为什么是线程不安全的

    1.因为springmvc默认是单例的,所以会有线程安全的问题,如果存在全局变量,因为全局变量是存在方法区的,而局部变量是放在栈中的,方法区是所有线程公用的,而每个线程都有属于自己的栈.所以如果使用单 ...

  6. 初级PM要做什么

    首先让我们看下这张图,产品经理进入公司后将要面临着许多工作 或许你有疑问,如果是产品助理的话,上面这么多工作都要去做吗? 其实不然,初级产品经理由于工作经历有限,对行业的研究以及对市场的把控是有视野限 ...

  7. oracle序列的使用

    第一天:序列的使用 在oracle中sequence就是所谓的序列号,每次取的时候它会自动增加,一般用在需要按序列号排序的地方.  1.Create Sequence  你首先要有CREATE SEQ ...

  8. Java程序员职业生涯规划完整版:从程序员到CTO( 摘)

    在技巧方面无论我们怎么学习,总感觉需要晋升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样我们清楚的知道我们大概处于那个阶段和水平. Java程序员 高等特性 反射.泛型. ...

  9. 学以致用十九-----shell脚本之引号

    shell脚本中引号也是有讲究的. 可以分为单引号‘ ’,双引号“ ”和 反引号 ` ` 具体区别来看一个例子 输出结果 可得出结论 1. 单引号括起来的字符都作为普通字符出现,如第4,7,10,13 ...

  10. JS图片验证码

    !(function(window, document) { var size = 5;//设置验证码长度 function GVerify(options) { //创建一个图形验证码对象,接收op ...