defer

java

Connection conn = ...;
try {
    Statement stmt = ...;
    try {
        ResultSet rset = ...;
        try {
            ... // 正常代码
        }
        finally {
            rset.close();
        }
    }
    finally {
        stmt.close();
    }
}
finally {
    conn.close();
}

go


conn := ...
defer conn.Close()

stmt := ...
defer stmt.Close()

rset := ...
defer rset.Close()

java 7, try-catch-resource 写法


try (Connection conn = ...;
     Statement stmt = ...;
     ResultSet rset = ...;) {

}

多值返回

各语言的

http://rosettacode.org/wiki/Return_multiple_values

var 和 :=

var v1 int = 10 // 正确的使用方式1
var v2 = 10 // 正确的使用方式2,编译器自动推导v2类型

v3 := 10 // 正确的使用方式3,编译器可以自动推导出v3的类型

var 可用类型默认的 “0” 值

:= 强制代码中初始化

可以作为taste来讨论,而非懒程序员和聪明程序员

goroutine

在语言级别强调一种编程方法/范式也是种语言的文化,Erlang便是前例之一

内置 Go routing 即体现了 对于工程上有意义

有些问题在语言层面解决要比在类库层面解决要简洁漂亮许多

Gorouting 并不是想颠覆传统架构设计,而是为了更好的适应新的架构设计

对于它应该如何使用,如何以此来设计一个应用,如何进行架构规划 需要更多篇幅

os 最小调度单元是“线程”,代码执行须落实到“线程”上

线程还是太重,占资源高,频繁创建销毁影响性,诞生出线程池之类的常见使用模式

“阻塞”线程往往不是一个好主意,线程虽然暂停了,但是它所占用的资源还在

线程的暂停和继续对于调度器都会带来压力,而且线程越多,调度时的开销便越大,这其中的平衡很难把握


C#跨平台坑

darwin/amd64上能跑的程序转到iOS/arm上出问题的例子数不胜数了,一般解决方案就是 换类库!

评: 为什么我不喜欢Go语言式的接口

https://my.oschina.net/chai2010/blog/122400

Go 隐式接口Duck Typing不是新技术, 但主流静态编程语言中支持很少

Go试图结合静态类型和 interface各自的优势


接口还规定了每个行为对应时间复杂度的”特征” ? 接口还规定了每个行为还包含是否会修改集合的隐藏要求 ?

Go 想绝对安全, 就传值. 想要性能(或返回副作用), 那就传指针


type Foo int

// 要性能
func (self *Foo)Get() int {
	return *self
}
// 要安全
func (self Foo)GetConst() int {
	return self
}



// foo_test.go

func TestGet(t *testing.T) {
	var foo Foo = 0
	if v := foo.Get(); v != 0 {
		t.Errorf("Bad Get. Need=%v, Got=%v", 0, v)
	}
}
func TestGetConst(t *testing.T) {
	var foo Foo = 0
	if v := foo.GetConst(); v != 0 {
		t.Errorf("Bad GetConst. Need=%v, Got=%v", 0, v)
	}
}

func BenchmarkGet(b *testing.B) {
	var foo Foo = 0
	for i := 0; i < b.N; i++ {
		_ = foo.Get()
	}
}
func BenchmarkGetConst(b *testing.B) {
	var foo Foo = 0
	for i := 0; i < b.N; i++ {
		_ = foo.GetConst()
	}
}



interface IPainter {
    void Draw();
}

interface ICowBoy {
     void Draw();
}

不能让画家小明去跟其他牛仔决斗,让他去送死

小王又会画,又是牛仔


class XiaoWang : IPainter, ICowBoy {
    void IPainter.Draw() {
         // 画画
    }

    void ICowBoy.Draw() {
         // 掏枪
    }
}


C++搞出函数重载(语义相似, 但签名不同), C#还搞了个支持同一个单词不同含义的特性

Go不支持这些花哨的特性

太复杂且没多大用处, 写出的代码不好理解(如果原作者不提示, 谁能发现Darw的不同含义这个坑?)

Go语言的哲学是: “Less is more!”

type XiaoWang struct {
	// ...
}

func (self *XiaoWang)Draw() {
	// ...
}
func (self *XiaoWang)DrawTheGun() {
	// ...
}

XiaoWang需要关心的只是自己有哪些功能(method), 至于祖宗关系开始根本不用关心

等到XiaoWang各种特性逐渐成熟稳定之后, 发现新来的XiaoMing也有类似的功能特征, 这个时候才会考虑如何用接口来描述XiaoWang和XiaoMing共同特征


type Painter interface {
	Draw()
}
type CowBoyer interface {
	DrawTheGun()
}