Go语言访问控制指南:Java开发者必读

本文详细对比了Go和Java在访问控制机制上的差异,解释了Go语言如何通过命名约定而非关键字实现简洁的访问控制,帮助Java开发者快速理解Go的设计哲学。

Go语言访问控制指南:Java开发者必读

Go支持多种编程范式,包括面向对象编程。但如果你从Java转向Go,可能会感到些许…呃…不适应。最明显的差异之一是Go完全没有访问修饰符。你可能会疑惑:

  • 我的publicprotectedprivate关键字去哪了?
  • Go提供了哪些访问控制机制?

别担心!Go的访问控制比Java更简单。完全不需要访问修饰符!

为什么Go只需要两种访问级别

Java提供了四种访问级别,从最严格到最宽松依次是:

  1. private:仅限同一类内访问
  2. package-private:仅限同一包内访问
  3. protected:允许同一包及(直接或间接)子类访问
  4. public:完全开放访问

现在让我们砍掉其中两个!

以包为封装单元

Go允许定义具体类型(相当于Java的类),但:

封装的基本单位是包,而不是像其他语言中的类型。 (来源:《Go编程语言》,Donovan & Kernighan,第6.6节)

例如:

结构体类型的字段对同一包内的所有代码可见。 (同上)

因此Go不需要区分privatepackage-private。现在剩下三种:

  1. private:仅限同一类内访问
  2. package-private:仅限同一包内访问
  3. protected:允许同一包及子类访问
  4. public:完全开放访问

没有继承机制

最重要的是,Go不提供继承机制。因此Go不需要区分package-privateprotected。最终只剩下两种:

  1. private:仅限同一类内访问
  2. package-private:仅限同一包内访问
  3. protected:允许同一包及子类访问
  4. public:完全开放访问

Go的访问控制机制

最终Go只需要两种访问级别:公开和包私有。不过Go的术语与Java不同:

  • 导出(exported):相当于public
  • 非导出(non-exported):相当于package-private

(“unexported"是非正式的同义词,但建议使用更正式的"non-exported”)

Go设计者选择用命名约定而非冗长的关键字来控制访问:

标识符被导出的条件:

  1. 标识符名称首字母是大写的Unicode字符(Unicode类别"Lu")
  2. 标识符在包块中声明,或是字段名/方法名

(强调部分)

示例:

1
2
3
4
5
6
package foo

var (
    Bar = "Bar"  // 导出
    baz = "baz"  // 不导出
)

结论

Go的设计追求易读性,其访问控制设计显著提升了代码可读性:不仅摆脱了繁琐的访问修饰符,通过标识符首字母大小写就能判断是否导出。这是阅读Go代码比Java更轻松的原因之一——当然这只是我的个人观点。你怎么看?

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计