是否包导出居然是靠首字母大小写来区分,写着写着,一个变量想修改为包外可见,居然要修改几十上百个文件。
这是一种什么样的思想....
1
LonnyWong 2023-08-21 21:28:12 +08:00 2
加一个函数不就好了?
|
2
lanlanye 2023-08-21 21:35:35 +08:00
|
3
lhbc 2023-08-21 21:36:17 +08:00 2
```
func Function() { function() } ``` |
4
tairan2006 2023-08-21 21:37:43 +08:00 via Android 9
你没有 IDE 么…
|
5
zhwguest OP ide 就可以不修改文件么?...
函数可以导出结构体的包含关系?... |
6
hsfzxjy 2023-08-21 21:48:33 +08:00 via Android
用编辑器的重构功能重命名,会舒服很多,vscode 下直接 F2
|
7
darksword21 2023-08-21 21:50:39 +08:00 via iPhone
lsp 直接 rename 不就可以了
|
8
zhwguest OP @hsfzxjy 我并不是说改名很麻烦,我其实抱怨的是,如果在定义处用 public/private 等定义的话,只需要修改一处就好了。但是现在这个 public/private 伴随着每个使用它的地方。有十几个文件使用了它,就要修改十几个文件。并不是说麻烦,而是说太不优美了。
|
9
hsfzxjy 2023-08-21 22:01:48 +08:00 via Android
确实,这点同意
|
10
cmdOptionKana 2023-08-21 22:05:49 +08:00
虽然不优雅,但只能算个小缺点,毕竟不是很频繁发生的事情。而且,每种语言要说烦都能找出特别烦的地方,哪有完美哦。
|
11
aababc 2023-08-21 22:07:29 +08:00 2
问就是大道至简
|
12
mineralsalt 2023-08-21 22:15:17 +08:00 1
我今天也简单看了一下 GO, 确实很多语法很不合理, 完全就是为了和其他语言不同而不同, 根本谈不上优化和好用. 但是交叉编译二进制真的是好用, 真的爽. 如果语法能类似 kotlin 或 ts, 那也会舒服很多啊
|
13
zhwguest OP @cmdOptionKana 其实一个成员改变包可见性真的是很常见的事情。
|
14
hallDrawnel 2023-08-21 22:23:05 +08:00
用 IDE 很快就改了,问题不大。能很快改掉的问题都不大。就怕那种改不了的。
|
15
crysislinux 2023-08-21 22:25:49 +08:00 via Android 1
确实不太行,一点小事莫名其妙搞个大 pr
|
16
teli 2023-08-21 22:39:36 +08:00
如果一个变量,被几十、上百文件引用,这是更大的问题吧
|
17
cmdOptionKana 2023-08-21 22:47:59 +08:00 1
@zhwguest 在 Go 里一般习惯尽量用 public ,只有大概率确定不对外可见的才 private 。
因为,不管任何语言,从 public 改成 private 都肯定麻烦,也极少发生。而 private 改成 public 稍常见一点,那么,一开始不确定的你就一律先 public 嘛,从而把需要改的情形减少了 90%,等到稳定之后再看看,看到一些完全没有外部引用的,此时再从 public 改成 private 也不迟。 如果你按照其他编程语言那一套,优先 private ,那肯定麻烦。 |
18
zhwguest OP @teli 包内引用一个变量太多次都有问题了.....这算是....一个 student 的 id 还不准包内几十个文件引用?
|
19
zhwguest OP @cmdOptionKana 你没觉得这样太迁就一个语言了么?就为了一个 Go 的首字母大写,就摒弃了封装性原则,这不正是我吐槽的地方么?
|
20
jorneyr 2023-08-21 23:02:40 +08:00 2
Go 特立独行的地方很多,例如 Json 和 Struct 的属性匹配,泛型大家都用 <T> 而 Go 用 [T],错误没有堆栈信息最后还是要出一个包裹的 error ,更不用说各种 if err != nil 的判断了,特别影响业务逻辑的流畅程度。
|
21
cmdOptionKana 2023-08-21 23:04:13 +08:00
@zhwguest 以 Python 为例,它可能引入一个函数(或直接引入一堆函数),这个函数直接就成为一个本地名称了,也就是说会污染本地变量名,但 Go 引入的是一个包,那个包里的所谓 public 成员,不会直接污染本地名称的,比如引入 fmt, 那么不管 fmt 里面有啥公开成员,都要以 fmt.Print 的形式来使用。
因此,在 Go 里面封装不需要太紧张,污染问题本来就不大。 |
22
rekulas 2023-08-21 23:06:18 +08:00
用 go 多年了,从没遇到过你的烦恼,类库一般写下去的之后就能确定它的可见性了,如果经常需要修改你可能要想想是不是前期系统结构考虑不够周到
如果实在不想修改,加一个公共方法把私有成员映射出来也是一个办法,这种做法在各大类库也比较常见,一般都包含私有和公共结构体部分,如果需要操作私有成员的可以通过特定方法进行操作, 直接将私有成员修改为可见也不是一个推荐的方法,可能会导致一些安全问题. |
23
cmdOptionKana 2023-08-21 23:07:33 +08:00
@zhwguest 而且 Go 又不使用 Java 那种传统 OOP 的“继承”关系,因此可见性不需要那么严谨和复杂。
|
24
lightjiao 2023-08-22 00:03:35 +08:00 7
我觉得 golang 在国内之所以火是因为当初 goroutine 实现高并发 IO 的需求很简单,效率也很高
高并发 IO 的需求一度也带热了 Python ( Python 有 asyncio ),但是 Python 一时爽,重构火葬场,Python 很快在 web 领域凉了 尽管如此,golang 还是太简陋了,非常不适用于写业务需求,有地方为了避免变量逃逸甚至会把一个函数写到几千行,完全没必要 同时 goroutine 本身也不是十全十美,它浪费内存已经是众所周知的了 这里推荐感兴趣的了解一下 C# 的 async/await 异步模型,对满足高并发 IO 也非常容易实现,异步之间的通信也不需要 channel 那种额外绕一下的方式,对内存利用率高,运行时得力于 .Net Core 性能越来越好也不再是瓶颈。 C# 早早的实现了跨平台,高级语言也十分特性完备,推荐了解。 注:C# 是 async/await 鼻祖,python 等语言都是从它那里借鉴的 |
25
Vegetable 2023-08-22 00:10:55 +08:00 3
朋友,var A=a ,能看懂吗?
|
26
hanxiV2EX 2023-08-22 01:07:50 +08:00 via Android
大小写这个还好解决,一个文件夹必须是一个包就很痛苦,没办法把子目录放到一个包下。。。
|
27
cooltechbs 2023-08-22 01:35:04 +08:00
一楼正解,加个 getter 完事儿。
我个人写了几年都已经习惯了,反正 Go 的重构工具也很方便,自动修改所有引用基本没有不 work 的。然后改变量名的 PR 单独开一个,不和其他的 feature/bugfix 混在一起。 记得 Go 的定位是 Modern C 吧,语法“简陋”在当下是一股清流,除了 Go 还有其他语言的语法和 C 差不多简单吗 |
28
kneo 2023-08-22 01:49:04 +08:00 via Android 2
@cmdOptionKana 你这就属于胡说八道了。
|
29
MeteorCat 2023-08-22 01:58:49 +08:00 via Android
@cooltechbs Rust ,还支持 bindgen 自动把 c 语言转 rust ,rust 把 go 爆十条街
|
30
nuk 2023-08-22 02:10:41 +08:00
据说导出大写是为了可读性,如果是直接导出结构体字段的话,可以加个 get/set
|
31
yulon 2023-08-22 02:12:51 +08:00
改名改可见是少数事件,读代码是多数事件
|
32
kwanzaa 2023-08-22 02:24:50 +08:00
往好点想,这样可以让你 review 一遍哪里用了它,毕竟你这引用量非常大。
其实挺理解你这种焦躁感的,感觉问题不是出自 golang 身上。 |
33
voidmnwzp 2023-08-22 03:25:31 +08:00 via iPhone
@lightjiao 你说 goroutine 浪费内存就有点耍无赖了,一个协程栈最低 4k ,已经比其他编程语言占用低太多了,很多 jvm 都是一次性分配固定 1m ,你用 go 跑一百万个和用 Java 跑一百万个内存占用跟本不是一个量级,后者基本没办法做到,早就 oom 了,你这属于既让马跑又不让马吃草
|
34
james122333 2023-08-22 04:38:06 +08:00 via Android
一样的好嘛...你其它语言改可视度一样要改全部
不用改那只有原本就用 setter/getter function 才不用改 或着你有用 lombok 导致你有这样的错觉 golang 你照样可以自己写 setter getter golang 这样虽然丑了点但不是不可以接受 我更喜欢全小写加下划线 |
35
james122333 2023-08-22 04:50:24 +08:00 via Android
改字段名所有语言都要 refactor name 搂
就算没这功能也很好解决 字段唯一的状况一行指令就搞定了 你如果在 vim 底下用 vimgrep 挑选更改也可以 还可以更快点 |
36
dw2693734d 2023-08-22 07:31:52 +08:00
@jorneyr
go 的泛型这个的确是,看着很不舒服 |
37
dgqypl 2023-08-22 07:43:15 +08:00
你有发这个帖子的时间拿 IDE 都改完了
|
38
kiwi95 2023-08-22 07:45:49 +08:00 via Android 8
情绪这么不稳定还是不要编程了,一个大写导出就“恨死了”,再写下去早晚得抑郁。
|
39
Breacher 2023-08-22 07:57:05 +08:00 via iPhone
如果从 private 改成 public ,不也要改几百个文件?
|
40
ohwind 2023-08-22 08:34:09 +08:00
@tairan2006 你这逻辑很不可理喻
|
41
loveuer 2023-08-22 08:42:17 +08:00 4
不对吧,如果你一开始就是小写,那么必须同一个包才能使用,怎么可能到处都是引用,所以何来到处都要改的问题?那如果你一开始就是大写,现在要改 private ,同等情况就算 python ,java 也要改很多地方(或者借助 idea ,lsp )的 refactory ,所以何来吐槽呢?不要为了吐槽而吐槽啊?
|
42
GTim 2023-08-22 08:50:16 +08:00
@loveuer 同意,他这种方式是不想写方法,原则上来说,如果要对外能访问,又不想改可见级别,Java 难道不是另开一个方法么? Java 领域也没人敢把 private 的方法直接改成 public 的方法吧
|
43
cosiner 2023-08-22 08:59:11 +08:00
要修改多个文件是因为你改了函数名, 不是因为改了可见性, 虽然这是因为 Go 的可见性和函数名大小写绑定, 按照其他人说的, 如果只是想增加一个导出 API, 又不想修改太多文件, 可以加一个包装函数
语言风格有好处有坏处, 有人能接受, 有人接受不了, 不能接受就换, 换到满意为止 |
44
pluto1 2023-08-22 09:01:24 +08:00 via iPhone
go 本身就是为了工程而生的,各种杂七杂八的限制很多就是为了让大家按一个模子写,方便协作
|
45
Desdemor 2023-08-22 09:01:33 +08:00
换语言吧,搞多了你自己心情都要崩溃了
|
46
bruce0 2023-08-22 09:01:58 +08:00
我反而挺喜欢这个根据大小写判断 public 和 private 的, 要不然每个变量前面加个单词 好麻烦, C++ 虽然可以 作用后面全部, 但是有时候还要往前翻才知道到底是 public 和 private
|
47
cyrivlclth 2023-08-22 09:03:35 +08:00 via iPhone
说实话 一般 public 改 private 不管啥语言影响都挺大。 一个 private 改 public 的,能改动几十上百个文件?我的认知里一个 package 咋做到上百个文件的🫠🫠🫠
|
48
Narcissu5 2023-08-22 09:07:00 +08:00
ide 改简单倒是简单,都是对 code reviewer 实在是太残酷了
|
49
Smilencer 2023-08-22 09:07:35 +08:00
我这边建议你换语言呢亲
|
52
kiwi95 2023-08-22 09:25:25 +08:00 via Android
@ohwind 厌恶可以,恨死就极端了吧。你有见过完美的语言吗?我很想知道 op 或者你换到什么语言了
|
56
surbomfla 2023-08-22 09:41:23 +08:00
七天速成 Golang 都知道如何进行函数方法包外可见,OP 一点都不看,直接上来开写 🤡
|
57
learningman 2023-08-22 09:45:45 +08:00 via Android
本来不可见的,你是怎么写出上百个文件的
本来可见的,你改完了,本来也要全改一遍 |
58
githmb 2023-08-22 09:51:20 +08:00 1
我就觉得函数名大写太丑了所以拒绝学习这门语言
|
59
Mexion 2023-08-22 09:55:21 +08:00
大道至简是这样的😁
|
60
ziyeziye 2023-08-22 09:58:18 +08:00
吐槽逻辑不成立。
同#41 和#57 ,private 的情况,怎么实现几百个地方都引入的?本来 public 改成 private ,那其他语言外部使用的一样都需要大批量修改,和 go 又有什么区别呢? |
61
Bazingal 2023-08-22 10:03:41 +08:00 4
无论你吐槽什么,go 粉都有几十种理由解释为什么要这样设计,先进在哪里
|
62
ding2dong 2023-08-22 10:08:35 +08:00 1
这点确实不爽,什么 IDE 重构,一下子修改几十上百个文件,commit 太美了
|
64
itskingname 2023-08-22 10:09:38 +08:00
好像是为黑而黑,这种场景本来就很少见。
1. 原来是 private ,你要把它改成 public 。这个时候,原本外面就没有地方使用,你改了以后外面才开始使用。所以没有负担。 2. 原来是 public ,现在改成 private 。如果原来只有少数几个地方使用,改成小写不费力。如果原来有几百个地方使用,你有多大的胆子敢做这样大规模的重构?被几百个地方使用的公共函数,也敢轻易改成私有? |
65
lasuar 2023-08-22 10:10:43 +08:00
“成员改变包可见性真的是很常见的事情”,这是一开始的设计发生了问题,一两次还好,怎么还是常见的呢?
回到帖子本身的问题,如果一个成员已经是私有,怎么会在多处被引用,然后引发楼主所说的“修改几十个文件”。 短短几句话就暴露了水平,别把 V 站当贴吧。 |
68
troywinter 2023-08-22 10:15:56 +08:00
引用私有成员本身就破坏了封装性
|
69
pkoukk 2023-08-22 10:16:51 +08:00
一门语言的基础规则看都不看,直接上来撸?
那 c# 和 java 的默认 class 还是 internal 的呢,也不是 public 啊 |
73
codersdp1 2023-08-22 10:27:34 +08:00
建议换成 JAVA 呢
|
75
codersdp1 2023-08-22 10:29:25 +08:00
修改的时候只用修改一处,不用处处修改
如果是 ide 的话,改变大小写,也只用修改一处。 |
77
codersdp1 2023-08-22 10:31:16 +08:00
|
78
zhwguest OP @ziyeziye 我不就是说的包内引用么?包外引用是第一次(以前都不可见怎么引用),哪涉及到什么修改,我有什么意见?....
|
79
Slurp 2023-08-22 10:45:34 +08:00 via iPad 2
😁,Go 大道至简是这样的,大小写确定可见性的魅力,还搁着「改可见性的情况很少」,问就是你写的不对。
|
80
Slurp 2023-08-22 10:47:08 +08:00 via iPad 3
@codersdp1 😅咋不说 Java 有 IDE 的情况下很简洁。凡事要用 IDE 改善的地方,我只能认为设计的垃圾,可见性和名称挂钩是 sb 到极点的设计。
|
81
lightjiao 2023-08-22 10:56:41 +08:00 via iPhone
@voidmnwzp 我回答中说的 async await 无栈协程可以做到对内存的高效利用
据我所知 java 里没有 async await ,java 也是吃内存大户(但 kotlin 有 async await )。 也许你会说除了 java 和 go ,其他语言不好招人。但我想说的是:golang 本来也不好招人,吹的人多了,就好招了 |
82
lightjiao 2023-08-22 11:01:33 +08:00 via iPhone
@voidmnwzp 你提到的跑一百万个协程的内存与效率问题,可以搜索一下 async 与 goroutine 的对比
不是所有协程都是有栈协程( 4k 的栈大小),async 这种编译时的无栈协程对内存的利用率天然更好 |
83
xhxhx 2023-08-22 11:06:26 +08:00
惊了!第一次听说要把 id 改成 ID 的!
只需要新定义 Person.GetId 的方法就能解决的问题,为什么变成要修改几十个文件? 话说一个包下几十个文件,这就是十年服务端的功力吗,涨见识了 |
84
MoYi123 2023-08-22 11:09:45 +08:00
关于 code review, 你完全可以把 export id 拆出来, 分 2 次提交, 根本不会有什么问题.
|
85
whyso 2023-08-22 11:10:25 +08:00
用了快十年才发现这个规则?用了快十年还没习惯 go 特立独行的设计?现在吐槽是不是有点晚
|
87
gaifanking 2023-08-22 11:15:22 +08:00
@itskingname 仔细看,楼主讲的是原本 private 但是有很多包内引用,现在改成 public 这些无辜的包内引用也要跟着改
|
88
cmdOptionKana 2023-08-22 11:17:12 +08:00
看了附言。
1. 可以弄个 Person.GetId 方法 2. 一个包分几十个文件,这本身可能就有问题,又不是 Java ,分那么多个文件干嘛,徒增麻烦 3. 从你附言来看,这种改动还是少见的啊,你原本说常见,并不成立 4. 既然少见,顶多算个小问题吧 |
89
MoYi123 2023-08-22 11:24:46 +08:00
补充一下我熟悉的其他编程语言的情况
python, 用下划线区别 c++ ,public, private, 但是通常私有成员变量的命名会区别于公开成员变量比如, _name, m_name, name_ 感觉只有 java 是可以直接改吧? 但是 java 也是推荐 get/set. 不太懂你觉得好的语言是哪个? |
90
kiwi95 2023-08-22 11:29:27 +08:00 via Android
id 改 ID ,那再加一个 ID()方法是最简单的。GetID()命名不是推荐的 style 。再说 op 是要暴露给外界读,那加一个方法不是本来就是最优设计?
@ohwind #86 憎恨/恨死了这样的用语可能我用的少,无法共情你们。 |
92
Huelse 2023-08-22 11:49:19 +08:00
刚开始确实很难理解,就像我刚学 rust 的时候就很疑惑为啥其他基本类型是全小写,唯独 String 是大写开头的,后来我才突然意识到 String 不是基本类型而是个对象,char 才是基本类型。
因此你可以这样理解 go 的导出命名规则,大写就相当于是说明导出(对象)而不是内部(基本类型)。 |
93
lasuar 2023-08-22 12:45:39 +08:00 1
|
94
PureWhiteWu 2023-08-22 13:02:11 +08:00
为什么直接加一个 Export 函数不行?
|
95
dragonsunmoon 2023-08-22 13:22:38 +08:00
别问, 问就是 大道智减 😅
|
96
chaniqure 2023-08-22 13:36:35 +08:00
大小写这个还好,我开发过程中,觉得恶心的有两点,一个就是包,一个文件夹就是一个包,导致我想创建一个 util 包,里面包含 str ,json ,dict 那些公共的工具包,还不行,因为没有重载的概念,导致,util 得创建 str_util ,json_util 这样的文件夹,另外一个就是循环引用的问题
|
98
itskingname 2023-08-22 14:41:09 +08:00
|
100
voya 2023-08-22 14:44:50 +08:00 1
我曾见一位一开始写 java 的同事,觉得 golang 的 error 设计太繁琐,在公司的业务代码里自己按照 java 那一套封了一个 error handler, 然后被打回让重改。这点上不是 golang 不好用,而是他习惯了其他规则,一上来就觉得不合理,不对,连语言本身特性、设计都懒得去了解和思考
|