Go中的函数可以有多个返回类型,更明显的是输出参数。 例如:
func getThings() (int, Foo) { return 2, getFoo() } a, b := getThings()这有点像在现代C ++中返回元组,特别是在C ++ 17中的结构化绑定:
std::tuple<int, Foo> get_things() { return make_tuple(2, get_foo()); } auto [i, f] = get_things(); Garbage Collection(垃圾回收)与 Java 一样, GO 具有自动内存管理, 因此可以信任在使用完这些实例之前不会释放它们, 也不需要显式释放它们。因此,可以放心地完成此操作,,而不必担心以后释放该实例:
func getThing() *Thing { a := new(Thing) ... return a } b := getThing() b.foo()你甚至可以这样做,不用关心和了解实例是在堆栈还是堆上创建的:
func getThing() *Thing { var a Thing ... return &a } b := getThing() b.foo()我不知道Go如何避免循环引用或不需要的“泄漏”引用,因为Java或C ++将使用弱引用。
我不知道如何,或者如果,Go避免了Java由于垃圾收集而间歇性放缓的问题。 Go似乎是针对系统级代码,所以我想它一定要做得更好。
然而,也像Java一样,并且可能像所有垃圾收集一样,这仅对于管理内存而非一般资源是有用的。 程序员通常很高兴在代码完成使用后一段时间内释放内存,而不一定立即。 但其他资源,如文件描述符和数据库连接,需要立即释放。 一些事情,如互斥锁,通常需要在明显的范围结束时释放。 破坏者使之成为可能。 例如,在C ++中:
void Something::do_something() { do_something_harmless(); { std::lock_guard<std::mutex> lock(our_mutex); change_some_shared_state(); } do_something_else_harmless(); }Go不能这样做,所以它有defer(),而是让你指定一个事情发生在一个功能结束。 这是一个烦人的延迟与功能相关联,而不是一般范围。
func something() { doSomethingHarmless() ourMutex.Lock() defer ourMutex.Unlock() changeSomeSharedState() // The mutex has not been released yet when this remaining code runs, // so you'd want to restrict the use of the resource (a mutex here) to // another small function, and just call it in this function. doSomethingElseHarmless() }这感觉像是一个尴尬的黑客,就像Java的试用资源一样。
我更愿意看到一种语言,以简明的语法给我所有的范围资源管理(包括析构函数),引用计数(如std :: shared_ptr <>)和垃圾回收,所以我可以有可预测的,明显的, 但可靠,必要时释放资源,垃圾收集时我不在乎。