文档章节

Go’s Type System Is An Embarrassment

Jerikc
 Jerikc
发布于 2014/08/30 11:56
字数 576
阅读 65
收藏 1

Go is one of the best tools out there today for heavy lifting and backend code. It’s my go to language when it’s time to bring out the big guns and I enjoy working with it immensely. That being said, its type system is an embarrassment. It’s meant to be clear and comprehensible yet it’s full of awkward surprises.

Lack Of Generics

Most modern type systems have some notion of generics. Generics allow types to interact with other types in a type-safe manner. Go has no support for generics. It’s possible to live without generics by using type assertions (casting) and empty interfaces but these are not checked at compile time. Some built-in functions of Go work with pseudo-generic types (e.g. len(), append()) so the language designers are clearly aware of the problem, and yet this pseudo-generic functionality is not exposed to regular users of the language. The compiler and the type system are there to help the developer; having to cast types back and forth in a statically typed language is just embarrassing.

Confusing Semantics Of Exported Identifiers

Many modern languages provide some mechanism to hide methods and data internal to various compilation units or data structures. This is a good thing; it makes programs more reliable by limiting interfaces exposed by modules and by abstracting away implementation details.

Most programming languages allow this by having a mechanism to expose or hide functions, data fields, and types. Go does this with a twist: it exports the lexical identifier, not program element (e.g. type or function) the identifier represents. As a consequence, if there are no identifiers involved, unexported program elements can leak into other packages. What does this mean? Consider the following example:

package p1

type hidden struct {
    Field int
}

func NewHidden() hidden {
    return hidden{Field:1337}
} 

package main

import (
    "fmt"
    "p1"
)

func main () {
    myHidden := p1.NewHidden()
    fmt.Println(myHidden.Field)
    myHidden.Field = 9000
    fmt.Println(myHidden.Field)
}

This example will compile and work. Go will have absolutely no problem with this as it’s not the “hidden” type that is unexported, only its identifier. Since the:=operator infers the type of the variable on its left side from the expression on the its right, there are no unexported identifiers involved. People on the golang-nuts mailing list seem to think that this makes the type system “easier to understand and explain” but in my opinion these sort of unintended consequences only make things worse.

In addition, the reflect package does not allow reading or writing struct fields with unexported identifiers (even if the field was reached without using any identifiers) which seems to completely contradict the philosophy of exporting being a strictly lexical concept.

The Verdict

If we were still living in the ’90s or Golang was a hobbyist or experimental programming language, these shortcomings would be acceptable. The year is 2014 however and Golang is heavily backed by Google itself so there is simply no other way to say it: Go’s type system is an embarrassment.

I don’t believe that the lexical exporting issue will ever be resolved, partly because it appears to be an inherent part of the language and partly because I don’t think the designers of the language will ever admit it’s an issue. On the other hand, I’m almost certain that generics will be added at some point, hopefully sooner rather than later. That will make things better.

本文转载自:https://functionwhatwhat.com/go%E2%80%99s-type-system-is-an-embarrassment/

共有 人打赏支持
上一篇: Diamond-Problem
下一篇: The Go Type System
Jerikc
粉丝 95
博文 246
码字总数 22757
作品 0
浦东
程序员
私信 提问
target triplets

Autoconf-generated configure scripts can make decisions based on a canonical name for the system type, or target triplet, which has the form: ‘cpu-vendor-os’, where os can be......

the_anaconda
2017/05/10
0
0
How Do I Install the Android Market on Android SDK

转自: http://www.tech-recipes.com/rx/10004/accessing-android-market-from-android-sdk/ ==================================================== 我在Android SDK4.0.3上按照步骤走一遍的......

晨曦之光
2012/05/21
174
0
使用SIP对C++类进行Python封装

本文来自于: http://pyqt.sourceforge.net/Docs/sip4/using.html#a-simple-c-example 本人翻译,欢迎转载,赠人玫瑰,手留余香。 Using SIP Bindings are generated by the SIP code generat......

openthings
2015/02/06
0
0
Racket 6.10 发布,Lisp 语言分支

Windows 10 创意者更新引入了一个 bug,使得图形程序诸如 DrRacket 可能引起蓝屏等问题,本次更新采取措施缓解了这一现象,Microsoft 已经获悉此 bug 并将在未来版本中彻底修复。 详细更新:...

MikeManilone
2017/08/03
382
1
[翻译中] 树莓派搭建Torrent服务器

In this tutorial I document what I did to set up Raspberry Pi (RPi) as a torrent server. Before you begin, please set up your RPi correctly. See:http://elinux.org/RPiEasySDCardS......

八宝粥
2013/07/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

如何开发一款以太坊(安卓)钱包系列2 - 导入账号及账号管理

这是如何开发一款以太坊(安卓)钱包系列第2篇,如何导入账号。有时用户可能已经有一个账号,这篇文章接来介绍下,如何实现导入用户已经存在的账号。 导入账号预备知识 从用户需求上来讲,导...

Tiny熊
今天
2
0
intellJ IDEA搭建java+selenium自动化环境(maven,selenium,testng)

1.安装jdk1.8; 2.安装intellJ; 3.安装maven; 3.1 如果是单前用户,配置用户环境变量即可,如果是多用户,则需配置系统环境变量,变量名为MAVEN_HOME,赋值D:\Application\maven,往path中...

不最醉不龟归
今天
4
0
聊聊ShenandoahGC的Brooks Pointers

序 本文主要研究一下ShenandoahGC的Brooks Pointers Shenandoah Shenandoah面向low-pause-time的垃圾收集器,它的GC cycle主要有 Snapshot-at-the-beginning concurrent mark包括Init Mark(P......

go4it
昨天
4
0
Makefile通用编写规则

#简单实用的Makefile模板: objs := a.o b.o test:$(objs) gcc -o test $^ # .a.o.d .b.o.d dep_files := $(foreach f,$(objs),.$(f).d) dep_files := $(wildcard $(dep_files)) ifneq ($(d......

shzwork
昨天
3
0
《万历十五年》的读后感作文4000字

《万历十五年》的读后感作文4000字: 万历十五年,即1587年,距今已过去432年。在明朝276的历史中,这一年很平淡,并没有什么特别之处。黄仁宇的《万历十五年》一书,有别于其他的历史叙述方...

原创小博客
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部