代码编辑器哪个好用_好用的代码编辑器

代码编辑器哪个好用_好用的代码编辑器本篇内容是根据 2019 年 10 月份 Codeeditorsa 音频录制内容的整理与翻译 在本期节目中 主持人与 RamyaRao 讨论了代码编辑器和语言服务器



本篇内容是根据2019年10月份Code editors and language servers音频录制内容的整理与翻译,

在本期节目中,主持人与 Ramya Rao 讨论了代码编辑器和语言服务器。分享了关于我们使用的编辑器、使用原因以及为什么要更换编辑器的想法。还讨论了语言服务器是什么以及它在连接编辑器及其支持的语言方面的重要性。我们还深入探讨了有效使用 VS Code 的各种方法,包括快捷方式、插件等。

过程中为符合中文惯用表达有适当删改, 版权归原作者所有.



Johnny Boursiquot:大家好,欢迎来到 Go Time---一个由多化嘉宾和特别嘉宾讨论所有与 Go 相关话题的节目。我叫 Johnny Boursiquot,今天与我一起的有 Mat Ryer 和 Jon Calhoun,还有我们的特别嘉宾 Ramya Rao,来谈一谈开发者最熟悉的工具---他们的编辑器。大家今天怎么样?

Mat Ryer:大家好,我对今天的节目非常期待。

Johnny Boursiquot:你是不是想要挑起战争?

Mat Ryer:不。

Johnny Boursiquot:我们不会那样做。今天的节目不会有那种事情。

Mat Ryer:不过这是一个有趣的开始,因为人们对他们的编辑器真的很有意见,不是吗?他们对编辑器有很深的情感依赖……我认为自从我们有了编辑器,这种情况就一直在发生。今天,很多人仍然使用 Vim 和 Emacs 来写 Go。我经常听到这类事情……所以是的,人们爱它。这是有道理的,因为你花了大量时间与这个应用程序在一起,尽管它基本上只是一个文本编辑器。它很火……

Johnny Boursiquot:哇,哇……只是一个文本编辑器?!等一下,等一下;在我们深入探讨之前,让我们先让我们的特别嘉宾打个招呼。嗨,Ramya。很高兴再次见到你。你好吗?

Ramya Rao:大家好,很高兴再次回来。我很好,而且我很期待听听 Mat 要说什么……[笑声]

Mat Ryer:我只是想要破冰。

Ramya Rao:是啊,当他说“我对这期节目非常期待……”的时候,我就想“好吧,你每次节目都得这么说吧”,因为你在这里啊……[笑声]

Johnny Boursiquot:哦,但这期节目……嗯,我不确定。

Jon Calhoun:其实他并不需要每期节目都这么说,因为他完全可以不上节目。

Mat Ryer:我随便说什么都行。

Ramya Rao:哦,明白了……

Mat Ryer:是啊,太棒了。

Johnny Boursiquot:[笑声] Jon,你最近怎么样?

Jon Calhoun:很好,很好。我也很期待这期节目。我觉得编辑器是非常有趣的话题,因为它真的影响了你如何工作,所以讨论和解释你如何使用它们会很有趣。

Johnny Boursiquot:确实如此。

Mat Ryer:等等,所以 Jon 可以说跟我差不多的话,然后就轻松过关了?他几乎是照搬了我的话……[笑声]

Johnny Boursiquot: 就像 Vim 和 Emacs 之间的对比一样……你知道 Vim 更好,但你还是要允许 Emacs 存在---嘿,我开玩笑的,开玩笑的。我们不要开始这个话题。好了,Ramya,上次你来我们节目时是谈论在 VS Code 中的 Go 支持,那期节目---我不记得具体的集数了,但我相信听众可以找到---我们聊了一些关于在 VS Code 中的 Go 支持的历史、插件、开发过程、你如何管理开源贡献等等。那期内容很好,但我们今天不想重复那些话题。不过我想知道的是,从那以后你都在做什么?你还在微软做与编辑器或 Go 相关的工作吗?

Ramya Rao:是的,当然。我想自那期节目已经过去两年了,那是在2017年。之后的几乎两年(或者说一年半)时间里,我仍然深度参与了 Go 的支持和插件开发。这段时间非常棒……但你知道,生活在继续,事情总会发生变化。最近我已经从 VS Code 团队转到了微软的其他部门,所以我在 Go 扩展上的投入时间确实减少了,但我对这个项目的兴趣、热情以及希望它变得更好的愿望依然不变。

Johnny Boursiquot:这太棒了。那么现在我们要去骚扰谁呢?在 Twitter 和社交媒体上提出功能请求和各种问题……[笑声]

Mat Ryer:好问题。

Ramya Rao:他们都躲起来了,因为他们不存在---还是我。

Johnny Boursiquot:哦,我的天啊……你还在背负这个重任。哇。

Jon Calhoun:我们是不是需要为你发布一个招聘广告?

Ramya Rao:是的,绝对需要。我想这是我们将在节目里讨论的一个话题,关于项目和管理方式如何随着时间推移而变化,贡献者的数量、类型以及贡献的种类如何发生变化,以及我未来希望建立的合作伙伴关系……所以是的,我希望在接下来的一个小时里能讨论这些内容。

Johnny Boursiquot:是的,我们现在可以稍微展开讨论一下这些话题,趁我们还没有深入探讨偏好设置和其他内容之前……

Mat Ryer:我们不会讨论所有的偏好设置吧?[笑声] 我们没有那么多时间。

Ramya Rao:上次我在这个节目中,20分钟都花在了客户支持上。我不想重蹈覆辙。[笑声]

Johnny Boursiquot:确实如此。我们当时在线解决问题,教大家如何做事。好吧,接下来我们希望在 VS Code 中见到的(如果它还没实现的话)是稳定的 Gopls 集成。在过去的使用中,它有点不稳定,不过每次更新我都看到它在变得越来越好,使用体验也在改善,错误也在逐渐减少。现在它的状态如何呢?对于那些不知道 Gopls 是什么的人,你能否简单介绍一下它是什么,以及它如何改善 Go 在 VS Code 插件中的表现?

Ramya Rao:当然。目前 Go 插件的构建方式是利用现有的 Go 生态系统中的各种工具。它最早是在 2015 年 11 月至 12 月期间由 Luke Hoban (译者注: Typescript项目的联合创始人) 开始构建的。当时,几乎所有的编辑器都是通过这种方式来提供 Go 支持的,因为我们有一个丰富的工具生态系统,比如 Godef、Guru、Gocode 等,用于代码导航或者代码补全等需求。

几乎所有的 Go 插件都是这样构建的,它们位于编辑器和实际工具之间。每当你发出请求“嘿,给我这个符号的定义”,它就会向(例如)Godef 发送请求,获取结果,解析结果,然后以编辑器能够理解的方式返回给编辑器。

所以你可以想象这是一个由 5 到 6 个不同核心工具组成的大杂烩,再加上其他一些额外的工具提供附加功能,比如 Go modify tags 帮助你更新结构体字段,fillstruct 可以用默认值填充结构体……你有所有这些功能,都是由各自独立的工具提供支持。这种方式在很长一段时间内运作良好。但最近两年,由于 Go 语言和 Go 命令本身的变化,这种方式开始遇到问题。

Rebecca 在今年的 GopherCon 演讲中对此做了非常精彩的解释。如果你还没看过,强烈推荐去看那个演讲。我想演讲的名字是“Go, pls stop breaking my editor”。

Johnny Boursiquot:差不多是这个名字吧,哈哈。

Ramya Rao:她非常详细地解释了这种 Go 支持系统的现状,以及为什么语言服务器可以解决大部分问题。语言服务器的作用在于,它是一个单一的工具,可以处理所有的语言请求。也就是说,它可以提供代码导航、代码补全、诊断错误等所有功能。而且,它是一个后台运行的服务器。

如果你将它与 Godef 比较,后者每次请求都要从头开始计算一切,而语言服务器是后台进程,它监视你的文件,知道文件的状态,因此不需要每次都进行所有操作来找出符号的位置或补全内容。

总的来说,语言服务器是 Go 在编辑器中提供语言支持的解决方案。其他语言早已经有了这种支持---这就是为什么 VS Code 中许多其他语言的支持是通过语言服务器实现的。Go 相对来说进入这个领域比较晚。当我们意识到无法跟上工具系统和 Go 工具本身的变化时,开始尝试开发语言服务器。Sourcegraph 是第一个尝试制作语言服务器的公司,这个方案运行了一段时间。我们为 Sourcegraph 的 Go 语言服务器提供了支持。但随着时间推移,尤其是在模块系统出现之后,这完全改变了工具的范式,他们也发现自己无法跟上。

最终,Google 的 Go 工具团队站了出来,表示“嘿,我们知道,理解事情在不断变化。我们可以提供一个语言服务器来解决大部分问题。”这就是语言服务器在过去一年中开始发展的过程。有趣的是,这一切的起点是在 GopherCon---不是今年的 GopherCon,而是去年的 GopherCon……我记得当时我们有一群人---代表编辑器、Go 工具团队或社区的人---聚在一起讨论“嘿,事情在出问题。我们需要做些什么?”于是形成了一个小型工作组,我们与 Rebecca 和 Ian 紧密合作,推动语言服务器的开发。

Jon Calhoun:听到这些很有趣,因为我记得我曾经使用 Sublime Text 搭配 Go,这已经是很久以前的事情了……我记得其中一个原因是,我几乎可以确定该插件的开发者当时尝试制作自己的语言服务器……它的名字好像是 Margo,基本上它是一段在后台运行的 Go 程序,插件通过它与代码交互。

我觉得正是因为他们使用了自己的工具,导致了维护难度太大,最终这个插件逐渐落后了……这对我来说很令人失望,因为我曾经是 Sublime Text 的忠实粉丝,我非常习惯它。所以这让我尝试了其他工具,最终定居于 VS Code……但有一个通用的 Gopls 供所有编辑器集成是非常棒的,因为这意味着无论你喜欢哪个编辑器,你都可以获得优秀的支持。

Ramya Rao: 没错,这正是语言服务器的一个主要卖点。你只需创建一个语言服务器,它就能为多个编辑器提供支持……因为语言服务器协议本身已经很稳定,并且已经被许多编辑器广泛采用,所以任何支持该协议的编辑器都可以连接到 Gopls,提供与 VS Code 或其他编辑器中相同的支持。

所以最终,你不再是因为某个编辑器为特定语言提供的支持而去选择它,而是更倾向于选择编辑器本身的其他固有功能---那些与语言无关的特性。那将是我梦想中的世界,因为如果你在一个编辑器中获得某种自动完成的方式,那么在另一个编辑器中你也应该得到完全相同的体验。大家不需要再一次次重新发明轮子。

Jon Calhoun: 看着这种转变真的很奇妙,我还记得我刚开始工作时,每个人都有自己偏好的编辑器,而且这些编辑器通常是为特定语言量身定做的……当时这似乎是常态。虽然一直有像 Vim 和 Emacs 这样的编辑器存在,但很多人使用 Eclipse 等工具来写 Java……你会选择一个编辑器,熟练掌握它,然后随着时间推移很难再切换。所以现在我们进入了一个更加灵活的阶段,真的很酷。

Johnny Boursiquot: 我不太确定……我从这种共通的底层支持中学到的是,基本上这些编辑器之间有一个无差别的“繁重工作层”---借用 AWS 的术语……基本上,底层的基础设施已经存在,编辑器可以在此基础上构建。所以无论哪个编辑器,你都会获得相同的自动完成功能,因为这些责任被分配给了底层运行的服务器。像“你使用什么快捷键触发某些操作?你的编辑器看起来如何?你如何设置主题?”这些额外的东西,有些人可能觉得重要,有些人可能觉得无关紧要(这并不重要),这些都留给编辑器的实现者或开发者来处理,比如 VS Code 或 JetBrains 系列工具,或其他你喜欢的编辑器……但底层的内容---例如语言暴露出的功能,这些在所有编辑器中都是通用的,这些东西则由语言服务器来处理。

Jon Calhoun: 我的意思是---我同意你的看法,每个编辑器肯定会有一些不同之处;这也是我不使用 GoLand 的原因,不是因为它不好,而是因为他们对工作流程的一些假设与我的工作流程不太契合。所以并不是它不好,而是它对 Go 之外的某些东西并不是我喜欢的。

但曾经有一段时间,无论你使用什么语言,你都必须找到一个适合该语言的编辑器,这比其他一半的功能都重要。所以你不得不去学习一个新的编辑器设置,而现在我们已经到了一个这样的阶段---如果你是 Vim 用户,你几乎可以确定大多数语言都有一个语言服务器支持,你可以轻松在不同语言之间切换,因为语言服务器已经存在。但如果没有它,那就会变得非常具有挑战性。

Ramya Rao: 我相信在某些语言中,这种情况依然存在……因为我听说有些人一直在使用 C#,他们宁愿坚持使用 Visual Studio,而不愿转向 VS Code,因为他们仍然觉得两者之间有很大差距。这可能归因于几个方面。一方面,你已经习惯了某种方式……现在,即使轻量级的编辑器给你提供了支持,你也必须重新学习很多东西,这与语言无关,而是与工作流程有关,正如我们刚才讨论的那样。

所以工作流程肯定与编辑器紧密相关。如果仅仅涉及语言支持,那么语言服务器可以介入,消除这个差距。我对一些人的解释是,如果你把你在编辑器中看到的东西分为数据和行为两部分,行为和交互是来自编辑器的,而数据可以来自语言服务器。所以我们希望进入这样一个世界:所有编辑器都能给你相同的自动完成,当你按 F12 试图导航时,它们都能带你到相同的文件。而它们如何做到这一点,速度有多快,默认的快捷键是什么,它的外观如何,它的预览窗口是什么样子---这些都是交互、行为和用户界面,它们属于编辑器的范畴,而不同的编辑器可以对此做出不同的实现,你可以根据这些来评判编辑器。

Jon Calhoun: 是的,我确实能理解你说的,比如使用 C# 的人不太愿意切换。我曾经和某人在 Twitter 上有过一次交流,我们基本上是在讨论“我用 Vim 或 Emacs 来解决这个问题,你会怎么用 VS Code 或其他编辑器解决?”有趣的是,看到这些例子时,我发现真的有所不同……如果你提出一个太具体的问题,比如“我想要做这个确切的事情”,那么是的,一个编辑器可能比另一个编辑器更合适。

但是如果你只是说“这是我要解决的总体问题;我有一段文本,我需要更改特定单词的大小写”,那么我发现,很多时候在 Vim 中,人们会想到宏(macro),他们会记录自己执行一次操作的过程,然后重新应用这些宏。但在 VS Code 中,至少很多我认为是高级开发者的人,他们是使用多选的方式进行的。所以他们会选择所有需要编辑的地方,然后一次性完成操作。他们不是在应用宏,而是同时对所有内容进行操作。

所以看到这些工作流程的不同真的很有趣,如果你试图让某人从一种编辑器切换到另一种编辑器,那将完全改变他们思考问题和解决问题的方式,因此很难比较“哪个更好”,更像是“你擅长哪种流程”。

Johnny Boursiquot: 我发现很难---我觉得你触及了这个问题---切换到不同的编辑器……但我觉得有时我切换编辑器的原因之一是因为“同侪压力”(peer pressure)也是其中的一部分……[笑声]

Ramya Rao: 在所有原因中,我真的没想到同侪压力会是你切换编辑器的原因,Johnny,真的没想到……

Johnny Boursiquot: 我是认真的……我记得当 VS Code 刚出来的时候……那时我也是一名 Sublime 用户,我甚至试过一段时间 Atom……那些编辑器有它们的问题,但我想:“你知道吗,我不想切换……”在那之前,我一直用 Vim,而且全职使用。我现在仍然用 Vim,只是不再是全职了。

无论如何,对我来说,切换总是有成本的。但让我最终跨过那道坎的是---我总是会去编辑器的网站,查看功能列表……我想:“我要坚持用我的编辑器。哦,它有这个功能?这还不错……”你知道,我会羡慕其他编辑器的某些功能,然后我会在我自己的编辑器的插件目录中搜索,看看是否有类似的功能。

我觉得很大一部分---也许有些开发者也会认同---是“好吧,我的团队成员都在用什么?或者那些在讨论这个话题的人在用什么工具……”所以你会有一种想要归属感。我认为我们不应该低估同侪压力对你最终选择哪种编辑器的影响。

Jon Calhoun: 这真的是同侪压力吗?抱歉,我让 Mat 先说……

Mat Ryer: 没关系,你先说。

Jon Calhoun: 我的意思是,虽然你可能是因为别人也在用而去用同样的工具,但这也有好处,比如你可以随时走过来问团队里的某个人:“我该怎么做这个?” 如果你是团队里唯一一个刚学 Vim 的人,你可能会遇到很大困难。

Mat Ryer: 是的,这也可能反过来,比如一个 Vim 用户可能会问:“我怎么能做到按一个键就进入文件呢?”

Johnny Boursiquot: [笑]

Mat Ryer: “这真的很棒,我该怎么实现呢?”然后你发现“哦,VS Code 有这个功能,所以我可能会切换过去。” 我现在用的是 VS Code,Ramya,我想我之前说过了,非常感谢你们为它做的所有工作……但真的,每次有更新,带来明显的改进时,感觉真的很好,而且这个好感觉会传递给每个使用它的人。每次要更新时我都会感到非常兴奋。

Ramya Rao: 当我还在 VS Code 团队的时候,每次发布新版本后,我们都会收集反馈,无论是通过邮件还是 Twitter,我们会看到一些最受欢迎的功能……每次看到人们对发布说明和新功能的赞赏时,我们都会感到非常开心……对很多人来说,每个月当发布说明出来时,阅读它们本身就带来了纯粹的喜悦感,比如“哇,好棒的新功能!我得试试!” 所以……对不起,刚刚一下子让我想起了这些。

Mat Ryer: 是的。

Johnny Boursiquot: 但说实话,我现在有点跟不上阅读发布说明了,因为我发现自己实在无法跟上新增的功能。真的,现在有太多你可以使用的东西了,我只好说:“好吧,我会专注于我每天使用的12个快捷键,并试着掌握它们。” 因为对我来说,实在有太多东西了。当然,这些都很好,不同的人会觉得不同的东西更有用,但我现在的状态是:“好吧,这是我日常使用的东西。只要新功能不破坏我使用的内容,那我就满意了。”

Mat Ryer: 我确实可以去参加一个像 GopherCon 那样的研讨会,专门针对不同的编辑器,比如 VS Code。做一些深入研究,找出那些功能并展示它们。因为我也是一样,实际上它能做的事情比我想象的还要多。我实际上在 Twitter 上问大家他们最喜欢哪些插件,发现了一些非常棒的插件……从彩虹括号(rainbow brackets)到其他一些插件,彩虹括号会让括号的颜色对齐……

Johnny Boursiquot: 我装了那个,我装了那个。 [笑声]

Jon Calhoun: 那个插件确实很棒。

Mat Ryer: 是的,这就是我问那个问题的原因。还有一些其他的插件,它们真的很出色。我喜欢的是,我们中的任何人都可以扩展这个编辑器。如果有什么特定需求,我们也可以贡献代码。有时你可能只需要为你的团队开发一些东西,可能不值得分享,但我敢打赌,如果你为自己解决了一个问题,其他人也可能需要。

你想为 VS Code 写扩展必须用 JavaScript 吗?

Ramya Rao: 是的,VS Code 的扩展必须用 JavaScript 编写,因为这是它能够与 VS Code 交互的方式。所以……你可以绕过这一点,但……JavaScript 很简单,而且我们大多数的入门指南,尤其是关于扩展开发的部分---我们去年花了不少时间改进文档,特别是关于如何扩展 VS Code 的部分。所以我们有大量针对编辑器不同部分的示例,展示如何扩展它。比如如何扩展文件资源管理器?如何在左侧的活动栏中添加一个新视图?如何在下方的状态栏中添加一个状态栏项目?如何做这个,如何做那个……已经有很多现成的例子了。

所以如果你是那种想尝试扩展 VS Code 的人,可能觉得“哦,但我不会 JavaScript”,其实有很多入门点可以帮助你入门。已经有很多模板和脚手架可以帮助你。所以我们希望去年团队所做的工作确实降低了为 VS Code 编写扩展的门槛。

Jon Calhoun: 从个人经验来看,我可以说确实如此……至少从我看到的情况来看有这种感觉。曾经有一段时间,我觉得你必须是全职的扩展开发人员才能做一些复杂的事情……但现在已经到了一个阶段,你可以找到一个与你想做的事情足够接近的例子,然后开始朝着正确的方向前进,真正取得进展,而不会感到“哦,我得从头开始学一遍这个东西。” 这是一个非常不错的进步,至少我上次检查时是这样,它真的很棒。

Ramya Rao: 是的,即便你不想花太多时间在 JavaScript 上,你也可以用你自己熟悉的语言编写东西,然后通过命令行调用它……就像 Go 扩展做的那样。它创建了一个名为 Godev 的子进程,获取结果,解析后返回给 VS Code。所以你也可以选择保持 JavaScript 部分非常轻量化,而将所有繁重的工作放在 Go 或任何其他能够提供命令行工具的语言中,然后通过命令行调用它。

Mat Ryer: 这是个不错的主意。如果我要开发一个扩展,我可能会这么做。我喜欢 JavaScript……我只想说,我喜欢 JavaScript。在 Go 社区中,开 JavaScript 的玩笑很常见,但我并不这样。我喜欢它。

Jon Calhoun: 其实我唯一不喜欢 JavaScript 的地方是,我不喜欢按照“应该”的方式写 JavaScript。我写 JavaScript 的方式更像写 Go 代码。

Mat Ryer: 嗯……这没关系。

Jon Calhoun: 那既然你们都不介意,我其实挺喜欢JavaScript的。

Ramya Rao: 嗯,只要你的扩展能正常工作,我觉得没人会在意……[笑]

Mat Ryer: 是啊……不过Jon,如果你用Go的风格写JavaScript,可能你会用到的只是JavaScript的一个子集吧。

Jon Calhoun: 对,我几乎没怎么用箭头函数之类的东西,但我觉得这只是因为我不太熟悉它们。我还没怎么深入使用这些东西,所以还不太习惯。

刚才Johnny提到他在编辑器里只用了大概12个快捷键,我很好奇你们是不是也有这种感觉。因为当我和别人聊或者看他们实际使用编辑器时,我感觉编辑器能做的事情五花八门,但他们常用的功能也就七八个,而这些功能覆盖了他们90%的使用场景。我认为这很正常,因为你可能不会一直做那些复杂的操作……你们觉得自己属于这种类别吗?

Ramya Rao: 当我刚加入VS Code团队时,周围的人都在用各种炫酷的快捷键,但我完全没有动力去学它们……因为我从来不是一个重度使用键盘的人。我不介意用鼠标,也不介意因此失去那10%-20%的速度提升,但随着时间的推移,我确实学会了一些快捷键,并一直在使用它们。

但自从我换了团队后,看到其他人做事的方式,我有时会告诉他们“嘿,你知道有快捷键吧?”然后他们就会惊讶地说:“我不知道可以这样做!” 如果让我分享一些,我会先提到这些。比如在当前文件中搜索符号,Ctrl+Shift+O。它会给你一个下拉菜单,显示文件中的所有方法和变量。

Jon Calhoun: 在Mac上是Cmd+R吗?

Ramya Rao: 不,是Cmd+Shift+O。

Jon Calhoun: 因为Cmd+R做了类似的事,比如如果你在一个Go文件中,它会显示你定义的所有类型。

Mat Ryer: 我没有那个功能……

Jon Calhoun: 不过也有可能我已经改了快捷键……[笑]

Mat Ryer: 太棒了……

Jon Calhoun: 抱歉了。

Mat Ryer: 听众们可能还需要你的设置文件,请放在节目笔记里,谢谢。

Jon Calhoun: 其实我有录制设置一切的视频,而且我也有导出我的所有设置文件,所以我可以把这些给大家。

Mat Ryer: 那听起来真是太吸引人了,我很想看。

Ramya Rao: 是啊。所以我经常用Ctrl+Shift+O,在处理一个很大的文件时,这个快捷键能让我快速导航到另一个方法……如果你想跨文件搜索符号,可以用Ctrl+T,那可以在整个项目中搜索。不过要提醒一下,基于你使用的编程语言,这个功能可能会有点慢。

除此之外,我觉得Zen模式蛮有趣的,尤其是当你在做演示时,如果你不想让屏幕上出现太多杂乱的内容,你可以切换到Zen模式。

Ctrl+B---前几天我告诉某人你可以用Ctrl+B来隐藏侧边栏,他们觉得很搞笑。因为当你在分享屏幕并且放大字体时,远程的同事看不清小字体,结果你的屏幕一半是文件浏览器,另一半才是你真正的代码。Ctrl+B可以帮你隐藏侧边栏。

Mat Ryer: 对我来说是Cmd+B,而Jon可能已经把它映射成了别的东西。[笑]

Jon Calhoun: 你们是指整个侧边栏,还是……?

Ramya Rao: 是的。

Jon Calhoun: 我觉得左边最细的那条是Cmd+B,而Cmd+KB是隐藏文本文件部分,这个快捷键源自Sublime Text。

Ramya Rao: 好吧,大家不要听Jon的。

Jon Calhoun: 如果你安装了Sublime的快捷键扩展,可能会得到和我类似的设置,因为我就是这么迁移过来的。

Ramya Rao: 噢,原来如此。

Ramya Rao: 对,这是一个很有趣的点。我想我上次来的时候也提到过……有专门为快捷键设计的扩展,尤其是当你从其他编辑器迁移过来时。我们真的很想确保从其他编辑器过来的人能感到像在家一样,他们多年使用的快捷键不需要重新学习……所以我们发布了包含更新快捷键的扩展,可以匹配他们之前使用的编辑器。当然,不是完全匹配你个人的设置,但通常来说是这样的……

Mat Ryer: 比如Jon用的那些快捷键,我们可能永远也不知道,所以……

Ramya Rao: 是的,可能我们需要一个“Jon的快捷键”扩展……[笑]

Mat Ryer: 不要吧。

Ramya Rao: 还有最后一个,Ctrl+Backtick(译者注: 即反引号),可以切换终端,这也非常有用。因为我们大多数人都会时不时地用到终端,Ctrl+Backtick是我经常用来快速切换到终端开始工作的快捷键。

Johnny Boursiquot: 我有个怪问题……有没有人把VS Code的终端全屏,然后在里面用Vim?[笑] 还是只有我这样?

Ramya Rao: 这是你的忏悔吗?[笑]

Mat Ryer: 听起来确实像忏悔。

Johnny Boursiquot: 是的,我确实这么做过……体验还不错。虽然感觉有点浪费……

Mat Ryer: 这样你就能融入那些给你压力要你切换编辑器的人了……

Johnny Boursiquot: 是啊,“我确实在用VS Code啊……”[笑]

Jon Calhoun: Johnny在VS Code的终端里用Vim,而我这边努力想完全摆脱VS Code的终端……

Ramya Rao: 哦……

Jon Calhoun: 问题是---我用iTerm2,它有个全局快捷键,不管我在电脑的哪个工作区,只要按下快捷键,终端就会弹出来……我已经习惯了这个操作,现在几乎不可能打破这种肌肉记忆。而且它已经配置得非常符合我的需求,我不用再去折腾它了。所以我可能可以学着喜欢VS Code里的终端,但我觉得学会它的成本不值得。

我知道的一个快捷键是Cmd+Shift+U……它可以调出底部的一个窗口,但如果你按两次,它会让整个窗口消失……因为有时候它弹出来但我不想要,我就得按两次来快速让它消失。

Mat Ryer: 是的。

Jon Calhoun: 就是这种奇怪的快捷键,或者是我在使用过程中慢慢学到的。

Mat Ryer: 这就是问题所在……人们最终会变得非常迷信。Jon,你按的那个快捷键---Cmd+什么加U按两次?[笑] 我觉得这不是真的……

Jon Calhoun: 好吧,Cmd+Shift+U调出“输出”窗口。如果你再按一次,它会让窗口消失。所以当控制台随机弹出来时,你按一次,它会切换到那个标签页,再按一次,它会把整个窗口关掉。

Ramya Rao: 我觉得它的行为像是一个“聚焦+切换”的组合。所以如果它没有聚焦,它会先聚焦到那里,然后当它已经聚焦时,再按一次就会切换掉。

Jon Calhoun: 这就是我不想学每个标签页的快捷键,但有时只需要把它关闭的原因……因为就像Ramya提到的Zen模式,这对我来说也很有趣……我从来不用Zen模式。我基本上是通过快捷键关闭左侧边栏,然后用其他工具来移动窗口或者调整布局……我更常用的是Cmd+Shift+N,这个快捷键会打开一个新的VS Code窗口,而不是新标签页……然后我会把它放到我想要的位置。

还有一些其他的快捷键我经常用,可能其他人不太用,这很大程度上取决于你做的事情……因为我经常录制视频,或者演示我的编程过程,Cmd+Plus和Cmd+Minus(译者注,即右上方的加/减按键),以及Cmd+Shift+Plus/Minus,这些快捷键我经常用。一个是调整编辑器的文本大小,另一个(我想是通过扩展实现的)会调整侧边栏、标签菜单之类的东西……不过我想默认情况下,所有这些都会通过Cmd+Plus/Minus一起缩放,你需要一个扩展来区分这些操作。

我发现对我来说,这种方式更有效。当我尝试GoLand时,发现没有简单的方法来调整字体大小,这对我来说有点艰难……因为当你录制视频或教学时,你需要大字体,这样即使观众在手机上看,也能看得清楚。但是当你自己编程时,你不想用24号字体,那样太难受了。所以就是这些小细节……这些真的很有趣。

Mat Ryer: 我也有一个……可以分享我的吗?你们都知道复制粘贴,对吧?[笑] 这真的很棒。不过我真正想分享的是Ctrl+Minus,你可以通过这个快捷键浏览你之前去过的地方……所以当你在调试时,了很多文件,跳来跳去进入各种“兔子洞”,当你想回到之前的位置时,你可以按Ctrl,然后每按一次Minus,就会跳回你上一个位置……我觉得这个功能非常有用。

Johnny Boursiquot: 这真不错……我通常是通过搜索之前的位置来找我在哪……

Jon Calhoun: 这是一个不错的快捷键。我知道一个专门针对Go语言的快捷键,我特别喜欢,就是“跳转到定义”,我的快捷键是Cmd+Option+Down。我想这应该是大家通用的吧……

Johnny Boursiquot: 如果你用Vim绑定的话,这就是GD。我只是随便说说……

Jon Calhoun: 好吧……我喜欢这个快捷键的原因之一---这取决于你使用的编程语言,但在Go语言中我特别喜欢它,因为所有内容都在源代码中有文档记录……所以它是快速跳转到文档的方式,这在编程时非常棒。

另外,我喜欢它的第二个原因是,如果你想构建一个接口,你可以直接跳转到你想围绕它构建接口的函数定义,快速复制代码,这样你就可以迅速构建接口,而不用担心参数的命名;你可以直接复制它们。这让在Go中做这样的事情变得非常容易。

Mat Ryer: 是啊,这听起来不错。

Ramya Rao: 我有种感觉,咱们可能会把所有听众搞糊涂了,因为我们谈了太多快捷键……

Mat Ryer: Jon会的。

Jon Calhoun: 是的,我会。[笑声]

Ramya Rao: ……尤其是因为每个人都在用自己定制的扩展。我没有,我用的是默认设置……

Mat Ryer: 我也是。

Jon Calhoun: 所以我才试着推荐“跳转到定义”。这就是它的名字。

Ramya Rao: [笑]

Mat Ryer: 是的,我也喜欢当你悬停在符号上时,能看到弹出的文档信息……无论如何,任何类似的功能都非常有用。这很有趣---Ramya,你之前提到过语言服务器有一个一致的API。这是否意味着所有语言足够相似,可以用这种抽象的方式表示出来?

Ramya Rao: 是的。这不是因为语言是否足够相似,而是当你在编辑器中使用语言时,你会期望得到的功能。任何语言的使用者都希望能够跳转到符号的定义,比如Jon刚刚提到的“跳转到定义”。任何语言的使用者都希望悬停在一个符号上,并获取更多信息,比如“它的签名是什么?”或它的文档说明。任何人在编写代码时都希望根据他们输入的内容和单词在文件中的位置得到一些智能提示……诸如此类。

有一整套语言支持功能适用于所有语言……这就是为什么我们能够设计出API,称之为语言服务器协议(LSP),它为几乎所有这些请求和功能提供了钩子。稍后我们可以在笔记中提供一个链接,如果你查看协议文档,你会发现有很多钩子。你可能不会想到有这么多可以使用的钩子,但的确有很多适用于各种语言的功能。

当然,某些语言可能不适用某些功能……那就跳过它们。但对于任何语言,我们应该能够为其提供一个语言服务器,来为你提供这些功能。比如,go to definition(跳转到定义)、hover(悬停)、completion(代码补全)---这些都适用于所有语言,为什么不呢?

Jon Calhoun: 我能想到的另一个功能是查看某个东西的使用情况。我记得是“引用”……我不记得快捷键是什么了。

Ramya Rao: 是的。

Jon Calhoun: 但查看这种信息,比如“这个类在哪里被使用过?”或“它在哪里被引用过?”几乎在任何语言中都是通用的。

Ramya Rao: 是的,查找引用,或者甚至是查看一个接口---谁实现了这个接口?不仅仅是它在哪里被引用,而是谁实现了这个接口?我之前提到的符号搜索---每个文件、每种语言都有特定的结构;有函数,有类,有接口……每种语言都有定义它们的方式,而编辑器会以结构化的格式显示这些内容……至于你叫它们接口还是其他名字,那取决于语言。但无论你使用什么语言,看到结构化的内容都是共通的需求。

Mat Ryer: 是的,这很有道理。我也喜欢VC Code中的一些功能,尤其当你是编程新手,或者当别人不是程序员时,这些功能会让他们感到惊讶。有时候人们会看着你工作,问“你在干什么?”然后他们会说“哦,真糟糕,我走了。”但在此之前,他们会看到一些东西,比如对我来说是Cmd+D,这是选择,能选择整个文件中所有出现的特定文本。这对我来说非常有用,而且还有一个变体,可以选择文件中的所有内容。这是一个快速选择多个相同文本并同时处理的快捷方式,我觉得非常有用。我曾以为这会是一个看起来很酷但不实用的功能,但实际上非常实用……当人们看到你同时处理多个内容时,他们会觉得你很聪明,尽管你只是用了快捷键。[笑]

Ramya Rao: 是的……Cmd+D让我想起了---我稍微扩展了一下这个用法。嗯,"扩展"这个词在谈论扩展的时候用有点不合适。抱歉……我在处理大型日志文件时,如果我想删除一些噪音,并且我知道噪音出现在某些带有特定单词的行中,我会用Cmd+D或“更改所有出现的内容”来选择这些行,然后再用另一个命令将光标移到行尾。有一个命令可以让你“只把光标移动到行尾”。然后我可以用Shift+Home,或者其他组合键,取决于你用的是Windows还是Mac,选中整行,按Backspace删除它们。

Mat Ryer: 是的。

Ramya Rao: 当然,你可以用正则表达式之类的东西来处理……但对我来说,这种方式是最简单的,可以快速删除那些行。

Jon Calhoun: 你可以用这个功能做很多有趣的事情。如果你结合使用扩展,你会发现有一些扩展可以更改文本大小写。这样你可以很容易地把Go的字段转换成JSON结构体标签,或者把文本转换成蛇形命名法之类的东西……因为很长一段时间,我甚至不知道有些内置功能可以自动生成结构体标签,因为我太习惯用多选了,导致我懒得去学其他功能。

Ramya Rao: 是的。我强烈推荐试试“添加标签/删除标签”命令。它们是由fatih开发的工具gomodifytags支持的。这个工具非常好用,而且你可以更改设置,比如你更喜欢驼峰命名法或蛇形命名法,只需更改设置,然后就可以随心所欲地使用这个命令了。

Johnny Boursiquot: 我觉得我的下一个问题可能会把我们从快捷键的讨论中带离出去……

Mat Ryer: 哦,我也觉得是……

Jon Calhoun: 那让我先说一句……Mat,你刚才说多选像是个花招。

Mat Ryer: 是的。

Jon Calhoun: 我想说,当你在Chrome中按Cmd+D时,你会意识到它绝不是花招。不是因为我想要书签,而是我想要多选功能,但它不起作用。[笑]

Mat Ryer: 对。

Johnny Boursiquot: 有趣的是,我好像碰到过一个Chrome扩展,它使用Vim绑定来导航Chrome。我试了一下,然后觉得“好吧,这有点过了。”要是真喜欢Vim,才会用它来浏览网页。

Johnny Boursiquot: 很长一段时间以来,我一直告诉自己,“好吧,除非你能完全掌握编辑器的使用,熟练运用Cmd/Ctrl键,飞速在文本中导航……否则你就不算是一个真正的(用了招聘行业里不太合适的术语)‘忍者’或‘摇滚明星’程序员。” 就像好莱坞经常刻画的程序员和“黑客”那样,屏幕上的代码飞速滚动,3D立方体在空中飘浮,类似那种荒谬的场景……但基本上,我曾经认为,掌握你所用的工具、语言,与你在编辑器中的操作流畅度直接相关,你的手指有多快,决定了你是不是一个合格的开发者。你觉得将一个开发者的成长与他们在编辑器中的流畅操作联系起来,这种看法公平吗?

Jon Calhoun: 在回答这个问题之前,我能先问一个问题吗---你没有安装VS Code的3D城市插件吗?

Johnny Boursiquot: 不,我没有……[笑声]

Ramya Rao: 哇……那是什么?

Jon Calhoun: 好像并没有这个插件,但……如果有人做了一个让我可以在3D城市中飞行来寻找我的代码定义的插件,我会觉得“这太棒了”。

Mat Ryer: 是的,我们绝对可以实现这个。这个主意太棒了。这就是我们想要的,当Go出现在电影中的时候。

Johnny Boursiquot: 对,3D可导航城市。

Jon Calhoun: 老实说,我并不认为如果你没有完全掌握你的工具和记住所有快捷键,你就不算是一个合格的开发者……但我觉得随着你不断使用这些工具,你会逐渐发现一些常用的快捷键,并且会用得越来越多,最终它们会自动记在脑中,不用思考就能按出来。而且我觉得这会随着时间的推移自然而然地发生,但这并不意味着如果你不记得一大堆快捷键,你就不是一个合格的开发者或只是初级开发者……因为我见过非常聪明的人,他们编程速度较慢,但他们在解决复杂问题上比其他人更有优势,因此即使他们编程速度慢,他们仍然会比别人更快完成任务,因为他们在其他方面做得更好。

Ramya Rao: 是的,我完全同意……因为我相信我们的行业,作为软件工程师和问题解决者,所涉及的远不止打字和使用编辑器。所以我不认为这会让你成为一个不合格的开发者,我也完全同意Jon所说的一切。但我想用一个与我个人经历相关的比喻来说明这一点……

还记得你第一次使用计算机或打字机的时候吗?你必须一直看着键盘才能打字,对吧?

Mat Ryer: 嗯……

Ramya Rao: 后来我们中的一些人达到了一个不需要看键盘打字的阶段。这是一个很简单的能力,但它确实在某种程度上提高了你的速度,也减少了你在打字时需要投入的认知努力,不用再去看哪个手指按哪个键……所以我会说,知道快捷键和这些炫酷的操作可能会给你带来一些小优势,毫无疑问,但如果你不知道这些,也完全没问题。

Mat Ryer: 是的。唯一的例外是,如果你不知道如何保存文件,你会很难受。[笑声]

Ramya Rao: 嘿,这就是为什么我们有自动保存功能,对吧?

Mat Ryer: 哦,根本不需要手动保存。太棒了。[笑声]

Ramya Rao: 所以我会把这件事类比为,如果你觉得不看键盘打字能给你带来优势,那么也许了解一些快捷键也会给你带来一些优势。

Mat Ryer: 是的,我记得过去看到别人用Vim时感到非常受挫,或者是其他类似的工具。因为我起步阶段比较基础,学的是VB,后来是ASP.NET之类的东西……而且我曾经用记事本来写代码,因为当时工具还不完善,我知道的唯一方法就是用记事本。

Johnny Boursiquot: 我不知道该为你感到同情,还是对你感到佩服……[笑]

Mat Ryer: 同情吧……同情。当时我看到有人用Vim,他们做的事情让我目瞪口呆,非常令人敬畏,甚至有点让人畏惧。我感觉“好吧,我这边用的是记事本……”每次按Tab键就有八个空格,你知道我的意思吧?而且每次按Tab键,光标移动得太远了。我还记得当时心想:“为什么要跑到那么远的地方去?”

Mat Ryer: 是的…… 所以,如果你感受到任何压力,我鼓励你不要担心,就像Ramya说的,这不仅仅是打字而已。

Ramya Rao: 没错。

Jon Calhoun: 确实有些事情会带来一些挑战,但这并不是最重要的---因为我曾在KEDIT中编写Java程序,它就像Linux上的记事本一样。任何写过Java的人都知道你需要导入很多东西,我基本上必须在开始时导入所有需要的内容。所以我有一长串 “这是我需要导入的内容”。这些都是一些小程序,毕竟是在学校里写的,所以问题不大…… 但随着时间的推移,你会学到更好的方法来处理这些事情。不过,即便没有这些工具,你仍然可以学到很多,并且作为开发者不断进步。

Ramya Rao: 那我们要继续讨论键盘快捷键吗?

Johnny Boursiquot: 是的,我以为我们已经讲完了…… 好吧,那我们继续吧……

Jon Calhoun: 我可以提出一个有争议的话题吗?

Johnny Boursiquot: 当然,你还有五分钟。

Mat Ryer: 这次不是关于中东问题吧,Jon? [笑声]

Jon Calhoun: 不是。

Mat Ryer: 那就好。这真不是个合适的播客主题。

Johnny Boursiquot: [笑声]

Jon Calhoun: 所以…… 语法高亮和颜色。你们对这些有什么看法?我之所以说这是个有争议的话题,是因为我知道Rob Pike似乎不太在乎颜色…… 我不是要嘲笑他---每个人都有自己的偏好---但对我来说,在某些特定情况下,颜色还是非常有用的。例如,当我写字符串时,如果其中一部分颜色突然变化,我就知道我可能做错了什么,比如未正确转义某个引号。这是一个非常清晰的提示,能减轻我思考"我有没有做对"的负担。

所以我很好奇,你们是否有类似的情况,如果你们也喜欢语法高亮和颜色的话。

Ramya Rao: 说实话,我从来没仔细考虑过。默认的颜色设置对我来说就很好,我从没想过"我是否应该把它改成黑白模式"。

Mat Ryer: Rob Pike好像也不使用固定宽度的字体。他随便用什么字体…… 我猜是一个好用的字体,不是Comic Sans……

Jon Calhoun: 不是Comic Sans。 [笑声]

Mat Ryer: 我怀疑是。如果他用Comic Sans写Go代码,我会很惊讶……

Jon Calhoun: 也许这取决于他写的程序。他可能会说"这次的程序会很有趣,我们需要一种愉快的氛围。" [笑声]

Mat Ryer: 我想,如果方法和函数的颜色不一样,你可能会得到一些提示。字符串的例子就是很好的说明,Jon…… 因为你说得对,如果你没有正确转义某些东西,或者你试图转义却没有成功,颜色的变化会给你一个提示,这种反馈非常有用。除此之外,对我来说,我只是想让自己的眼睛在工作的同时感到舒适。

Johnny Boursiquot: 我有时候会改来改去,但大多数时候我还是保留了颜色设置。说实话,这取决于你从中获得的价值。我觉得Jon的理由很充分。对我来说,可能是因为年纪渐长,我已经看代码很多年了。如果默认有颜色,那很好,我没问题。但如果没有,我仍然能够浏览代码。所以,这不代表你作为开发者的能力是否强大,喜欢颜色与否只是个人偏好……

不过,在我们结束之前,我想从Ramya那里了解一下她对VS Code中Go语言支持的下一步计划。你现在主要追求的是稳定性,还是你觉得还有一些重要的功能可以添加来提升用户体验?你现在的想法是什么?

Ramya Rao: 如果在模块出现之前有人问我接下来要做什么,我的答案总是调试支持。所以过去一年我们一直在逐步改进,增加了一些小的改进。调试方面在过去一年里有了很大的提升。今年我在GopherCon的闪电演讲就是关于这一点的。但总体来说,这是我想在扩展中多加考虑的一个领域。

当然,模块出现了,语言服务器也出现了,Rebecca和Ian的团队做得非常好,不断改进这些功能并让它们运行得更好。所以对我来说,这两个部分是我关注的重点。由于语言服务器是使用Go编写的,而且有一个团队在负责,他们比我更熟悉这方面的工作,所以我更多关注调试功能的改进。

有一些合作伙伴对调试功能感兴趣,我与他们紧密合作,尽我所能帮助Rebecca团队改进语言服务器支持。但大多数时候,我的工作是处理用户提交的问题和功能请求,判断哪些功能适合集成到扩展中,哪些可以作为独立的扩展存在。

在最初的一年里,我会接手任何可以完成的事情。毕竟,这是编程,你总能找到方法把事情搞定,对吧?但随着时间的推移,我也学会了"也许这个功能可以作为一个独立的扩展存在,没必要捆绑在一起"。

所以目前的重点是尽一切可能帮助语言服务器获得更多的使用,并帮助用户适应它,报告问题,以便修复…… 因为它将是未来的方向。与此同时,我们也在调试领域尝试看看还能做些什么来帮助改进调试功能。

Johnny Boursiquot: 很好。如果有人想在这些计划上提供帮助,最好的方式是去查看GitHub仓库,对吗?还是有更好的方式?或者GitHub仓库仍然是主要的途径?

Ramya Rao: 是的,GitHub仓库是最佳去处。就语言服务器的角度来说,我建议大家都去试试。如果因为某些原因,它不适合你日常工作,或者对你们的大项目不友好,也许你可以每周或每天抽出一点时间来尝试一下…… 因为开启和关闭它非常容易。你不需要完全依赖语言服务器。

所以请大家试一下,并报告---报告问题,报告哪些有效,哪些无效…… 因为反馈是我们改进的途径。尤其是在这次GopherCon上,很多人来找我说"我们喜欢VS Code,但过去一年里情况不太好,很多东西因为……" “当然,我们理解。” “你能告诉我们什么时候能恢复到之前的状态吗?”

恢复到之前的状态的方式就是帮助语言服务器变得更好…… 你可以通过尝试它来做到这一点。即使你不每天都用,哪怕一周用一天,报告问题,我们一起让它变得更好。这样我们就能回到以前VS Code对Go开发者来说非常友好的状态,然后我们就可以专注于其他事情,比如调试、代码片段,甚至VS Code本身。

我上次提到的一件事是VS Code本身发展得非常快。我们讨论过,每个月都有很多新功能发布。新功能中也包含了许多语言扩展可以使用和集成的新API。所以一旦我们解决了基本的语言支持问题,我们就可以开始关注那些更高级的功能,比如代码操作和重构,看看如何最好地利用VS Code提供的这些钩子。我们可以在解决了基本的语言服务器问题后专注于这些事情。所以还有很多事情要做,但我认为当前最紧迫的一步是推动更多用户使用语言服务器并报告问题。

Mat Ryer: 如果我们现在在用VS Code,如何开启Gopls呢?…… 对于那些还不知道的人来说。

Ramya Rao: 好的,我来告诉你怎么做,不过如果你忘记了……

Mat Ryer: 去Google搜一下吧。 [笑声]

Ramya Rao: 不…… [笑声] 扩展的readme文件中有说明,VS Code Go仓库的readme文件,或者你可以直接在扩展视图中扩展,它会显示readme文件。那里会告诉你如何开启它,为什么要开启它,以及所有的详细信息。所以如果你忘记了,可以去那里查看。

但简单来说,有一个叫use language server的设置,它是一个基本的true或false的设置;将其设置为true或false就可以开启或关闭语言服务器。

Mat Ryer: Jon,你也是这么设置的吗?还是你把它改成false和true了? [笑声]

Johnny Boursiquot: 哇……

Jon Calhoun: 我更喜欢字符串形式的"on"和"off"。

Johnny Boursiquot: 这话说得够酸啊…… [笑声]

Ramya Rao: 是的…… 这会提示你重新加载,因为一旦扩展被激活,它会选择是否使用语言服务器。当你决定切换的时候,它会要求你重新加载窗口。这就是如何开启或关闭它的方式。另外还有一些设置可以帮助你更好地诊断问题。所有的内容都记录在readme文件中。我们在仓库里也有一个wiki,那里记录了一些有趣的事实,如果你想尝试的话……

所以如果有人想帮助我们,试用语言服务器,并告诉我们你的体验。

Johnny Boursiquot: 太棒了。非常感谢你再次参加我们的节目,Ramya。每次有你来参加都非常高兴。同时也感谢我的联合主持人,Jon Calhoun和Mat Ryer。希望我们已经充分讨论了Jon的键盘快捷键…… 或者是他的一些缺点…… 不管是什么…… [笑声]

Ramya Rao: 我们得改一下这一集的标题……

Johnny Boursiquot: 改成"快捷键"?

Ramya Rao: 标题可能是"快捷键以及Ramya想说的其他事"。 [笑声]

Johnny Boursiquot: 太棒了,太棒了。好了,听众们,非常感谢你们收听这期节目,我们欢迎大家收听下一期节目。至此,我们告别了。

编程小号
上一篇 2024-12-12 14:51
下一篇 2024-12-07 15:48

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://sigusoft.com/goland/1524.html