Java程序员快速入门 go 语言
赵亮-碧海情天, yale8848, LeoXu, supe · · 6694 次点击 · · 开始浏览先来认识堆栈(例子)
为了满足大家的好奇心,我们将开始于一个麻雀虽小但五脏内全的例子,这个例子将是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
翻译于 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
翻译于 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
翻译于 1 年 前
2人顶
翻译的不错哦!
语法 声明声明的语法同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
|
func f(i, j, k int, s, t string)一个变量可以在声明它时初始化值。进行此操作时,可以指定变量的类型,但这并非必需的。当不指定类型时,则默认为初始化表达式的类型。
var v9 = *v2
如果一个变量没有明确地初始化,则必须指定其类型。在这种情况下,它将隐式地初始化为其类型的零值(0,nil 等)。在Go语言中没有其它某些语言中的未初始化的变量。
赵亮-碧海情天
翻译于 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
翻译于 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人顶
翻译的不错哦!
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
先来认识堆栈(例子)
为了满足大家的好奇心,我们将开始于一个麻雀虽小但五脏内全的例子,这个例子将是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
翻译于 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
翻译于 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
翻译于 1 年 前
2人顶
翻译的不错哦!
语法 声明声明的语法同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
|
func f(i, j, k int, s, t string)一个变量可以在声明它时初始化值。进行此操作时,可以指定变量的类型,但这并非必需的。当不指定类型时,则默认为初始化表达式的类型。
var v9 = *v2
如果一个变量没有明确地初始化,则必须指定其类型。在这种情况下,它将隐式地初始化为其类型的零值(0,nil 等)。在Go语言中没有其它某些语言中的未初始化的变量。
赵亮-碧海情天
翻译于 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
翻译于 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人顶
翻译的不错哦!
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们