Java程序员快速入门 go 语言

这篇文章帮助Java程序员快速入门Go语言。

本文将以一个有代表性的例子为开始,以此让Java程序员对Go语言有个初步认识,随后将详细的描述Go语言的各个构成模块,最后以一个例子来讲解Go语言与Java语言的不同点。

yale8848
yale8848
翻译于 1 年 前

1人顶

 翻译的不错哦!

先来认识堆栈(例子)

为了满足大家的好奇心,我们将开始于一个麻雀虽小但五脏内全的例子,这个例子将是Stack.java的Go语言版本。

//实现堆栈的包集合
package collection

//生成空堆栈
type Stack struct {
    data []interface{}
}

//压栈顶
func (s *Stack) Push(x interface{}) {
    s.data = append(s.data, x)
}

//弹栈顶,并删除栈顶
//如果是空栈将会引发运行时错误
func (s *Stack) Pop() interface{} {
    i := len(s.data) - 1
    res := s.data[i]
    s.data[i] = nil  // to avoid memory leak
    s.data = s.data[:i]
    return res
}

//返回栈大小
func (s *Stack) Size() int {
    return len(s.data)
}
  • 用纯文本在声明语句上方添加注释。
  • 申明的名字写在类型的后面。
  • 结构体和Java中类相对应,但结构体的成员只能是变量,不能是方法。
  • interface{}类型对应Java中的Object。它不仅能代表引用类型,同时也能实现Go语言的所有类型。
  • (s *Stack)表示申明一个方法,s对应于Java中方法隐式传的this参数。
  • 操作符:=表示申明和初始化一个变量,其类型由初始化语句决定。
yale8848
yale8848
翻译于 1 年 前

1人顶

 翻译的不错哦!

下面是是使用collection.Stackabstract数据类型的简单例子。

package collection_test

import (
    collection "."
    "fmt"
)

func Example() {
    var s collection.Stack
    s.Push("world")
    s.Push("hello, ")
    for s.Size() > 0 {
        fmt.Print(s.Pop())
    }
    fmt.Println()
    // Output: hello, world
}
将测试包package colloection_test和collectionpackage放在同一目录。第一个import声明“.”表示将要用当前路径中的包并同时命名为collection,“fmt”是标准库的包名,没有重新命名,所以就直接用包名fmt即可。
yale8848
yale8848
翻译于 1 年 前

0人顶

 翻译的不错哦!

概念上的不同点

  • Go没有类的构造器。Go提供结构体接口,类的继承以及动态方法查询来进行实例化,而非通过实例方法。接口同样用于Java中的泛型。
  • Go中不仅对象和数组可以有指向数据的指针,其它所有类型都有。对于任何类型T,都有一个指针类型*T与之相对应,其表明指向类型为T的值。
  • Go允许在任何类型上创建方法;方法的接收者,就是Java中this,可以是个值或是指针。
  • 数组在Go中是一些值。当数组作为函数参数传递时,函数将收到数组值的拷贝,不是指针。然而实际中,经常用slices作为参数;因为切片中有数组的引用。
  • Go中提供字串类型;字串就像是由比特序列构成的slices,但字串是不可变的。
  • 在Go中哈希表叫maps。
  • Go提过channels类型来在多线程,goroutines之间通信来实现并发。
  • 一般类型(maps,slices,channels)传参是引用,不是值。如果传参map,参数不是对map的值拷贝;如果函数里改变了map的值,函数调用者的map也将改变。这个和Java中map类似。
  • Go中访问权限有两种,和Java中public 和包private类似。如果声明的名称首字母大写就是public,否则就是包private。
  • Go用error类型取代Java中的异常,诸如访问文件到结尾、运行时刻panic,数组越界等等。
  • Go不支持隐式类型转换,必须是显式的。
  • Go不支持覆盖。函数名和方法名在同一作用域必须不同。
  • Go用nil表示空指针,而Java用null。
yale8848
yale8848
翻译于 1 年 前

2人顶

 翻译的不错哦!

语法

Syntax Terror

声明

声明的语法同Java比较是逆向的。你写上名字然后再跟着写类型。从左至右的类型声明也许读起来容易些。

Go                            约相等的Java写法
var v1 int int v1 = 0;
var v2 *int Integer v2 = null;
var v3 string String v3 = "";
var v4 [10]int int[] v4 = new int[10]; // v4 is a value in Go.
var v5 []int int[] v5 = null;
var v6 *struct { a int }   C v6 = null; // Given: class C { int a; }
var v7 map[string]int HashMap<String,Integer> v7 = null;
var v8 func(a int) int F v8 = null; // interface F { int f(int a); }

声明一般是采用一个关键字后面跟着被定义对象的名称,这种形式。关键字是const、type、var或者func其中之一。你也可以使用一个关键字后面跟着放在括号之中的一系列声明,这种形式。

var (
    n int
    x float64
)
LeoXu
LeoXu
翻译于 1 年 前

1人顶

 翻译的不错哦!

当声明函数时,你必须为每个参数提供一个名称,或者不为任何参数提供名称;你不能省略一些参数的名称并提供其它参数的名称。你可以用相同的类型来组织几个名字,例如:
func f(i, j, k int, s, t string)
一个变量可以在声明它时初始化值。进行此操作时,可以指定变量的类型,但这并非必需的。当不指定类型时,则默认为初始化表达式的类型。
var v9 = *v2

如果一个变量没有明确地初始化,则必须指定其类型。在这种情况下,它将隐式地初始化为其类型的零值(0,nil 等)。在Go语言中没有其它某些语言中的未初始化的变量。

赵亮-碧海情天
赵亮-碧海情天
翻译于 1 年 前

1人顶

 翻译的不错哦!

短声明

在函数内,可以用 := 进行短声明,比如:

v10 := v1
它等效于:
var v10 = v1

函数类型

在Go语言中,函数是一等公民。Go的函数类型表示有相同的参数和结果类型的所有函数的集合。

type binOp func(int, int) int

var op binOp
add := func(i, j int) int { return i + j }

op = add
n = op(100, 200)  // n = 100 + 200
赵亮-碧海情天
赵亮-碧海情天
翻译于 1 年 前

0人顶

 翻译的不错哦!

多重赋值

Go 允许多重赋值。右边的表达式先被求值然后赋给左边的操作数。

i, j = j, i  // 交换 i 和 j 的值(不用象传统语言中需要第三个临时变量).

函数可以有多个返回值,用参数括号后面的一个括号中的列表表示。返回值通过赋予一个变量列表来存储,如:

func f() (i int, pj *int) { ... }
v1, v2 = f()

空标识符

空标识符用下划线字符表示,它提供了一种方法来忽略由多值表达式返回的某个值,如:

v1, _ = f()  // 忽略f()返回的第二个值.
赵亮-碧海情天
赵亮-碧海情天
翻译于 1 年 前

1人顶

 翻译的不错哦!

分号和格式

不需要担心分号和格式,你可以用 gofmt程序创建一个标准的Go样式。虽然这个样式最初看起来或许有点古怪,但它同任何其它样式一样的好,而且熟悉以后会感觉越来越舒服。

在实践中Go代码使用分号不多。严格说,所有的Go语句都是由分号终止。不过,Go在非空白行的末尾隐式插入一个分号,除非该行明显未结束。这带来的影响是,在某些情况下Go不允许换行符。例如,你不能这么写

func g()
{            // INVALID; "{" should be on previous line.
}

g()后面会插入一个分号,使它成为一个函数声明,而不是函数定义。类似的,你也不能写

if n == 0 {
}
else {       // INVALID; "else {" should be on previous line.
}

 }后面else前面会插入一个分号,导致语法错误。

super0555
super0555
翻译于 1 年 前

1人顶

 翻译的不错哦!

条件语句

Go 不使用括号来包裹 if 语句中的条件,和 for 语句中的表达式, 以及 switch 语句中的值。但另一方面,它必须用花括号来包裹 if 或 for 的执行语句体。

if a < b { f() }
if (a < b) { f() }           // 不需要括号.
if (a < b) f()               // 非法(执行体未用花括号括起来)
for i = 0; i < 10; i++ {}
for (i = 0; i < 10; i++) {}  // 非法(表达式不需要括起来)
此外,if 和 switch 接受一个可选的初始化语句,通常用它建立一个局部变量,如:
if err := file.Chmod(0664); err != nil {
    log.Print(err)
    return err
}
赵亮-碧海情天
赵亮-碧海情天
翻译于 1 年 前

0人顶

 翻译的不错哦!

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。