网站安全怎么做,ftp上传wordpress主题,石泉政协网站建设方案,汕头网站推广排名本篇内容是根据2023年3月份#271 Cross-platform graphical user interfaces音频录制内容的整理与翻译
这一期与 Wails 和 Fyne 的创建者一起深入研究为不同架构和操作系统编写 Go 代码。 译者注: Wails的作者是在澳大利亚悉尼的威尔士人,github头像是威尔士的旗帜,Wails也是Wa…本篇内容是根据2023年3月份#271 Cross-platform graphical user interfaces音频录制内容的整理与翻译
这一期与 Wails 和 Fyne 的创建者一起深入研究为不同架构和操作系统编写 Go 代码。 译者注: Wails的作者是在澳大利亚悉尼的威尔士人,github头像是威尔士的旗帜,Wails也是Wales的同音字 Fyne的作者则是苏格兰人,在其他编程语言领域也有很多贡献,Fyne来自苏格兰的一个地名 两个人应该能算老乡了, 另外巧合的是,两个项目此刻在github的star数都是28.4k 过程中为符合中文惯用表达有适当删改, 版权归原作者所有. Mat Ryer 大家好欢迎来到《Go Time》。我是Mat Ryer今天我们要讨论跨平台图形用户界面。和我一起的还有我的联合主持人 Natalie Pistunovich。你好Natalie。
Natalie Pistunovich 你好Mat。新年快乐
Mat Ryer 谢谢这是什么节日
Natalie Pistunovich 波斯新年在春分这一天庆祝。
Mat Ryer 啊真棒。所以对于我们北半球来说这就是白天开始变长的日子。
Natalie Pistunovich 对白天的时间开始变长了。
Mat Ryer 是的。不过不是对所有人都这样因为我们今天的嘉宾还有来自澳大利亚悉尼的 Lea Anthony他是SafetyCulture的高级软件工程师也是Wails的创建者。对吧Lea欢迎。
Lea Anthony 非常感谢。很高兴再次来到这里。
Mat Ryer 是的很高兴你能回来。哦对了澳大利亚的网络会有延迟吧
Lea Anthony 是的会有一点。
Natalie Pistunovich 因为夜晚开始变长了……
Lea Anthony 没错。
Mat Ryer 是啊祝你好运。这真是有点奇怪…… 我有点不确定是否相信澳大利亚的存在。以后我们再聊这个。我从没去过只是有点怀疑。我喜欢提出问题仅此而已。
我们的另一个嘉宾是Andy Williams。他是来自苏格兰的技术领导者有超过20年的软件工程师经验也是开源贡献者。Andy你创建了Fyne这是一款用Go编写的图形用户界面包你还曾是Enlightenment和Maven的核心开发者这非常了不起。欢迎。
Andy Williams 非常感谢Mat。很高兴能在这里也很高兴与Lea和Natalie一起。希望大家今天过得愉快。我很高兴听到白天时间要变长了因为---你知道我们这儿在很北边能带来一点阳光就好了。
Mat Ryer 是的这很好。你的介绍也很礼貌。我希望以后的嘉宾都能注意到这一点。
Lea Anthony 记住了。
Mat Ryer [笑] 好的。首先图形用户界面…… 你们怎么发音你们说“GUI”吗
Andy Williams 我一直说“GUI”我觉得这是最简单的表达方式大家都知道你在说什么。直到有一次我看到有人做笔记…… 我在谈论一本关于GUI的书他们在记录要去读什么书结果他们写下了“gooey”黏糊糊的我就想“哦天哪我们这样说反而增加了理解的难度。”
Mat Ryer 是的确实。而且GUI的书…… 没人想读那样的书对吧你看不下去因为它就像是…… [笑声] Lea你说“GUI”吗
Lea Anthony 我是的。还有其他说法吗
Mat Ryer 也有“G U I”的说法。我听过。
Lea Anthony 不……
Mat Ryer Natalie
Natalie Pistunovich 我说“GUI团队”。
Mat Ryer 我喜欢这个。GUI。这个词还有点可爱。我确实曾在一个地方工作过那里有一个团队非常强烈地认为后端工程才是“成年人的工程”而前端只是把东西弄得好看…… 他们把“GUI”当成一种贬义词真是遗憾。
Lea Anthony 哇……
Mat Ryer 是的。
Andy Williams 我也听过有人把图形开发者和“GUI”称为“用彩色铅笔的骑手”但大概并不是出于好的意图。
Mat Ryer 是啊。我不知道为什么这很有趣。我确实觉得这种看法已经改变了。过去确实有这种想法---你有时还能在Twitter上看到有人为了赚取点击率或曝光度会说“HTML不是真正的编程”或者“CSS是编造出来的”这其实也不算错它确实是某种程度上的编造。但我认为前端工程在很多方面实际上更难视问题而定。至少在后端你有相对一致的输入输出。而前端呢谁知道用户会做什么他们是人类非常不可预测。他们可能点击任何东西。Natalie你说“GUI”吗
Natalie Pistunovich 我说“GUI”我还认为有时机器也会点击界面对吧这就是我们有验证码检查的原因。
Mat Ryer 是的没错。
Natalie Pistunovich 我们不希望机器点击某些东西这就是为什么我们要确保它们是人类。
Mat Ryer 让我想到或许在API编程接口上我们应该有一个问题“你是人类吗” 然后你必须回答“不是”才能通过。
Natalie Pistunovich 你刚刚发明了用户代理。[笑声]
Mat Ryer 好的我觉得我们已经解决了重要的问题。我们将称它们为“GUIs”。不过你们一般不会把Go和构建GUI联系在一起对吧Go通常被认为是一种系统语言用于后端服务、API之类的东西。但其实你是可以用它来构建GUI的对吧Lea
Lea Anthony 没错你可以。我认为Go是一种通用编程语言和大多数语言一样那么为什么不呢用Go开发GUI有什么不好的地方吗
Mat Ryer 我不知道。我不觉得有什么不好。Andy你怎么看
Andy Williams 我完全同意。Go非常适合开发GUI。有人可能会说“这不是这门语言的初衷。” 但正如Lea所说作为一门通用语言它的有用性并不由其标准库或最初的设计目的决定而是由人们发现它在哪些地方合适以及在哪些领域获得了发展。从我看到的情况来看---我相信在这通话中的其他人也有类似的感觉---人们正在积极使用Go来开发GUI并且发现它非常适合。如果你不再把它仅仅看作是为服务器而设计的语言而是看它的内存管理、垃圾回收、静态类型等特性它帮助你定义非常明确的API整体上非常可靠。而且如果Go能解决所有这些跨平台的挑战为什么不也用它来解决图形应用程序中的最大挑战之一---让应用程序能够运行在所有不同的平台呢我认为Go非常合适。
Mat Ryer 是的。或许我们可以深入了解一下你们的项目你们各自的项目都提供了跨平台图形界面的支持但实现方式却非常不同。Lea对于不熟悉Wails的人你能告诉我们怎么拼写它以及它是什么、如何工作吗
Lea Anthony 好的Wails的拼写是W-A-I-L-S。这是以前的一个文字游戏。当时我发现了一个叫WebView的项目我想用HTML创建一个图形应用程序原因是我在日常工作中已经在使用它所以这对我来说是熟悉的。我发现了WebView它很好用但我想要更高层次的体验。它缺少很多东西所以我想“为什么不自己写一些功能构建IPC进程间通信并实现前后端之间的通信呢它们是两个不同的世界。” 所以我花了很长时间来做这件事感觉有点像Rails或者说是像Ruby on Rails的那种感觉…… 所以这是一个文字游戏的结果。我有点后悔但也不完全后悔。所以项目就这样演变了…… 就像这个项目一样。
Mat Ryer 而且你还来自威尔士Wales。
Lea Anthony 是的。你会以为我会想到这一点吧[笑声] 但我没有。有一天我突然意识到“哦或许这就是灵感来源吧。” 但这个项目其实是为那些想用Go编写HTML应用程序的人设计的因此它提供了很多相关的工具。
Mat Ryer 所以你基本上是在写网页前端对吧
Lea Anthony 是的。我认为Go在生成网站应用程序方面还是有一定份额的所以这两个世界之间有一点关联…… 不过它已经逐渐演变成了一种类似Electron的东西现在有系统托盘菜单、应用菜单、对话框等。这并不是我最初的目标最初只是为了满足我自己写程序的需求。有趣的是在这六年或四年的时间里我还从未真正用它写过一个程序。所以…… 是的构建这个工具集实在太有趣了我就迷失在其中了。
Mat Ryer 太棒了。我喜欢这种现象就像你说的你是在解决自己的问题…… 你经常会听到类似的故事这也是我一直给年轻工程师的建议特别是那些刚入行的工程师就是要解决你自己的实际问题。真正解决问题才是我们在做的事情而技术只是实现这一目标的手段。
AndyFyne…… Fyne的工作方式和Wails不太一样对吧它采用了稍微不同的方式。
Andy Williams 是的完全正确。如果有人不知道的话我们也选择了一个奇怪的拼写它是F-Y-N-E而不是你一开始会想到的拼法…… 但它有一点地理上的联系。这是苏格兰的一个地方所以我们觉得挺合适的。
Mat Ryer 就像Wails和Fyne…… 这真的很棒。
Andy Williams: 我知道。灵感常常来自于意想不到的地方。你说得对当我们在设计Fyne时确实走了一条不同的路线。我过去做了很多原生应用开发但我也曾使用跨平台工具做开发尤其是在Enlightenment项目中这些工具有优点也有缺点。Apple的工具包确实有一些很棒的优势但当时它主要是单平台的…… 我还见过一些工具的兴衰比如Swing等(译者注: Swing是Java生态知名的图形界面工具)。然后有一天我坐下来想“其实应该有一种更好的方式可以用一种编程语言编写出符合惯用法的代码并且能够在任何平台上运行。” 于是我就采用了这个思路。我的基本架构非常简单设计了一个简洁的API结构之后我接触到了Go语言发现它非常适合这个架构。巧的是我在Go语言中没有找到类似的东西这当然是一个小小的惊喜…… 你说得对这确实使得开发者端的应用程序完全用纯Go编写。所以无论你是否喜欢这种方式它都和Go语言契合得很好你只需使用标准的结构体、接口、方法和函数来编写代码。这一方法既保持了代码的可维护性也带来了一些额外的好处…… 比如我们可以直接利用Go语言中非常强大的单元测试框架因为我们使用的是语言本身的构造。
因此从我想要实现的目标来看Go确实是一个不错的选择我也很喜欢这条路线…… 当然它也有一些权衡因为我们没有像基于HTML的解决方案那样获得一些实时编辑的功能。所以我们正在构建的是一些稳固的、经过良好工程化的应用程序…… 这正是Go擅长的领域。
Natalie Pistunovich: UI的测试是什么样的你会测试些什么
Andy Williams: 基本上Fyne的部件widgets都提供了基于行为的API。因此你的单元测试会测试这些行为。比如你可能会创建一个输入框然后你可以模拟在输入框中输入文本之后验证文本是否正确。你还可以使用我们的测试包模拟双击输入框并通过检查选中的文本来验证文本是否被正确选中。我们使用了很棒的单元测试框架当然有很多可供选择的框架Testify可能是我们使用的一个框架。通过这些测试我们能够非常快速地验证功能是否正常。
不过我们也意识到有时候你确实需要看到实际的效果。因此你可以测试渲染的状态把渲染结果保存为图像然后进行图形比较甚至可以通过程序进行比较。或者因为反锯齿和其他问题可能导致不精确的结果你也可以使用XML树来进行比较。不过真正好的一点是这些测试执行得非常快因为它们是基于内存的单元测试根本不需要显示在屏幕上这带来了很大的便利。
Natalie Pistunovich: 那当你测试某些操作时比如你刚才提到的双击按钮---这种情况是模拟双击事件发生吗还是你有一些外部脚本来模拟双击操作
Andy Williams: 我们并没有通过任何外部系统。因为它是在内存中执行的实际上发生的事情是我们加载了一个测试驱动程序它模拟了应用程序的运行。所以你的部件会在内存中的应用程序中完全加载但不会渲染到屏幕上。当你说“双击这个部件”时它会触发事件链就像用户在屏幕上双击了一样而不需要通过操作系统的连接。
Natalie Pistunovich: 这真酷。我必须说对于那些没有看直播而是之后听的人Mat有一台摄像头会跟随他移动。他来回走动时摄像头就会跟着他移动。所以你可以像看熔岩灯一样看着他移动…… 这解释了从现在到节目结束之间的所有尴尬的沉默。
Mat Ryer: [笑] 是的这是Apple Studio显示器之一它有一个广角摄像头然后通过软件跟踪你的脸。如果有其他人进入画面它会自动拉远…… 它还不错只是有时候你想暂时离开镜头但可能会忘记它会一直跟着你。
Andy Williams: 现在Natalie提到了熔岩灯我无法不联想到这个因为Mat的红色毛衣真的很契合这个描述…… [笑声]
Mat Ryer: 是的…… 我就像这样漂浮着……
Natalie Pistunovich: 如果这还不足以让人们开始看直播我不知道还有什么能做到。
Mat Ryer: 是啊。我想我们也在YouTube上直播。你可以直接观看---对吧Natalie我不太确定。
Natalie Pistunovich: 是的是的。我们在YouTube上直播至少有一个人确认正在观看。嗨Mike Dodson。我们很感谢你。
Mat Ryer: 哦嗨Mike。不过本质上这是一个播客不只是为Mike……
Natalie Pistunovich: 但今天我们在讨论视觉效果。
Mat Ryer: 是的我们确实在讨论视觉效果……
Natalie Pistunovich: 我们还可以讨论音频。我注意到Lea在你的仓库描述中你提到了你在编写代码时听的所有专辑……
Lea Anthony: 是啊我也不知道为什么要这么做但我想我在其他仓库中看到过类似的东西觉得这很有趣。这是一个分享一些不太知名乐队的好方法。我想那时还没有流媒体服务所以人们主要通过推荐找到音乐…… 不过我也不确定为什么要这样做但确实挺有趣的。有意思的是有些人实际上联系我说“我听了这个乐队真的很棒。” 所以…… 你们有人做过这种事吗你们没在其他仓库里见过吗
Mat Ryer: 不我从未见过。不过如果你去github.com/wailsapp/wails……
Natalie Pistunovich: …你也可以在节目笔记中找到这个链接……
Mat Ryer: 是的你会在节目笔记中找到这个链接…… 但说真的有多少人会读节目笔记你们会读吗我不读节目笔记。
Natalie Pistunovich: 我写了它们。 [笑]
Mat Ryer: 对你写了它们。 [笑] 谢谢你。是的单元测试的内容很有趣。在Fyne中前端代码本身是什么样的你最终会有一堆嵌套的对象来描述用户界面吗
Andy Williams: 是的如果你喜欢这种方式的话你完全可以这样做。你可以将用户界面的对象结构作为一个大的结构体来编写我们支持这种方式就像你在Go代码中处理任何复杂的结构化数据一样。不过构造函数的使用帮助我们将其拆分为更小的组件我个人很喜欢这种方式。我们的设计原则之一是保持封装性所以无论是标准部件还是任何第三方部件都可以在任何上下文中重用。所以如果你按照这种方式编写代码那么你可能会有一个函数来设置主屏幕这个函数可能会调用不同的函数将面板插入到父容器的正确位置例如“构建我的工具栏”或“设置我的树形布局”。我喜欢鼓励这种做法因为我喜欢简洁的代码喜欢小型的、只做一件事的函数这种方式非常契合我的编程风格。不过我通常会有一个结构体比如一个应用程序结构体或者每个屏幕都有一个结构体用来跟踪一些重要的元素比如输入框或输出部件以便稍后引用这很有帮助。
这种可插拔部件的优势与Go语言能够从任何地方导入第三方代码的能力完美契合。你可以通过导入第三方组件并调用其构造函数将其直接嵌入你的UI中。比如我们的终端部件---你可以在任何Fyne应用程序中嵌入一个全功能的终端因为它是一个可以随时嵌入的部件。这种灵活性在原生应用开发中是非常罕见的这也是我非常珍视的设计之一而这也是多亏了Go语言的设计才得以实现。
Mat Ryer: 是的。Lea在Wails中当你构建前端时它是什么样的是HTML、JavaScript…… 还有CSS吗
Lea Anthony: 是的。你可以像开发任何一个网站一样开发应用程序。你可以选择npm生态系统或者你喜欢的其他生态系统。你可以使用现有的工具包…… 这没什么好说的如果你曾经开发过网站那么你就可以开发一个应用程序。
Mat Ryer: 是的。我喜欢这种技能的可转移性。当然总有一些东西需要学习但如果你会Go语言又会做网页前端那么你就可以上手这些工具。我觉得这非常好也非常重要。开发者的体验在这些工具中非常重要因为传统上尤其是构建跨平台的图形用户界面还是有些复杂的。我曾为macOS写过一些代码试图与操作系统交互确实不容易你经常会感觉自己在舒适区之外。而这些框架很好地解决了这个问题。
不过告诉我一些关于跨平台的信息…… 对于许多人来说无论是GUI应用还是其他我们可能会遇到编写跨平台代码的需求。因为Go可以为所有平台构建所以这很容易吗尤其是图形化相关的部分---告诉我这容易吗
Lea Anthony: 是的。
Mat Ryer: 是这样吗仅仅因为你只需要写一次代码它就能正常工作但不可能吧对吗
Lea Anthony: 我认为当然可以。这是我们都在追求的梦想。而且绝对是可以实现的。我不会说为工具包开发这个目标很简单但我们的目标正是如此。你有一个应用程序你可以在你的系统上运行它并且知道它在其他系统上也会完全相同地运行无论是不同的架构、不同的操作系统还是桌面、平板设备、手机等---只要目标平台被支持你基本上可以保证应用程序会以完全相同的方式工作。
Mat Ryer: 对于用户来说这很重要。那么告诉我一下构建这个过程吧。写跨平台的代码---无论是写GUI还是其他Go的开发者只需针对不同的架构编写代码。当然你可以为任何架构构建代码但当你与前端组件交互时每个操作系统的情况不都不一样吗
Lea Anthony: 我认为前端组件的交互本身在不同的操作系统中并没有太大的不同但每个操作系统提供的东西确实略有不同。例如文件对话框。在一个操作系统中你可能可以在本地对话框中创建目录和文件夹但在另一个操作系统中你可能无法做到这一点。这种本地工具包之间的差异---我指的是操作系统提供的内容不是我们自己的工具包---我认为弥合这种差异是相当困难的。Electron的处理方式是它基本上向你提供了所有选项然后你需要自己决定每个选项适用于哪个操作系统它会告诉你“这是用于Mac的”或“这是仅用于Windows的”。我认为这是一个经典的问题没有好的解决方法。
我早期采用的一种方法是如果某功能不能在所有操作系统上实现那么干脆不做这样你就能在所有平台上保持一致。但后来用户会回来问“那这个功能呢” 比如我们做xbar时就是一个很好的例子。在Mac的托盘图标中可以显示文本但在Windows中却不能。所以如果你编写一个需要显示文本的应用程序那么移植到Windows时就会遇到一个很大的问题。我相信还有很多类似的例子。
Mat Ryer: 是的。所以这涉及到在设计抽象层时要做得好这是你面临的挑战之一…… 你是选择最小公分母的方式确保所有地方都能正常工作还是有某种功能API来处理如果调用了不支持的功能是否在运行时抛出错误它是如何工作的
Lea Anthony: 我觉得我们可能会有不同的答案……
Andy Williams: 是的是的。我认为这不一定是运行时错误而是某些功能只是没有被支持。所以如果你打开一个文件对话框并请求能够创建目录你可能会得到一个不支持该功能的对话框。这是没办法的事情。所以我认为目标二进制文件在不同平台上会有略微不同的功能但代码可以是相同的。也就是说Go代码可以是相同的但……
Mat Ryer: 那对于某些功能在一个操作系统中存在而另一个操作系统中不存在的情况呢有没有这种情况
Andy Williams: 我正好可以回答这个问题因为这是与原生系统能做什么和不能做什么相关的。在Fyne中我们并不是追求最小公分母。我们实际上提供了很多功能来替代本地系统应该做的事情。
例如我们有一个文件对话框它会显示为使用我们工具包构建的应用程序的对话框而不是本地系统的对话框这意味着你在那些没有完整图形支持的系统上也有一致性和完全可用的应用程序。我特别指的是一些像uBSD这样的系统可能是Open或NetBSD它们并不是完全图形化的平台但Fyne应用程序可以直接加载并运行而且完全正常工作。所以我们不得不编写大量功能代码以填补这些空白。
当然有些功能不可能在所有平台上都可用。移动设备有一些特定的功能它可以提供而桌面系统则没有反之亦然。你提到的xbar和系统托盘的概念很有趣因为移动设备实际上并没有这个概念。当然有通知区域技术上可以做一些类似的事情但概念上并不相同。
实际上在Fyne API中我们借鉴了类型检查的概念使用接口来提供扩展功能。所以应用程序接口提供了所有在任何系统上都能正常工作的功能比如你可以显示通知、打开窗口或在本地浏览器中打开URL等。但系统托盘不在其中因为我们不能保证它能正常工作。
所以我们有一个desktop包它定义了应用程序的扩展功能。你可以在代码中进行类型检查所以在运行时应用程序的实现会有所不同但你的代码可以通过编译器检查确保你不会做出可能在运行时导致崩溃的操作或者使用不可用的功能。我不会说我们每次都能做到完美抽象层可能会有问题但我们非常努力地确保如果你在IDE中可以自动完成那么它就一定可以运行。
Mat Ryer: 这很有趣。所以这些是接口你通过类型断言和第二个参数即ok来检查从而知道某个功能是否可用
Andy Williams: 是的没错。你可以对你的应用实例进行类型检查比如对desktop.app进行类型检查这样你就可以访问系统托盘。如果你检查的是mobile.app它会暴露设备的相关信息比如屏幕方向和一些其他传感器这些在桌面设备上是没有的。
Lea Anthony: 那这会根据你正在开发的平台而改变吗比如当你在Windows上开发并且想要在托盘图标上显示文本当你输入点号时看到的内容和其他平台一样吗
Andy Williams: 这是个很好的问题。如果你的IDE能理解你当前正在测试的目标平台那是可以的。所以你需要在IDE中设置一些变量调整它以适应你想要查询的平台这样你就可以“欺骗”它让它认为类型断言会生效或不会生效取决于已设置的类型。所以也许自动完成并不总是最好的方式。不过话虽如此它应该仍然有效因为它知道接口只是不知道类型断言是否会成功。所以大多数情况下它应该是可行的。当然我相信有些情况下可能不那么直接但我认为---大体上它是可行的。
人们会问“我觉得我发现了一个问题。我做了这些事情但它没有达到预期的效果所以这是已知问题吗” 我希望能说“如果你在代码中告诉它做某件事而它没有做到那么这可能是一个bug而不是某种配置错误或用户失误。” 因为我们努力保持API的简洁并确保它是易于理解的基本上可以保证能正常工作。
Natalie Pistunovich: 引入泛型后你们的工作是否变得更轻松了
Andy Williams: 说实话泛型的引入暂时还没有影响到我的工作……我知道它会让某些事情变得更好但我很乐意坐在一旁等待其他人努力探索它的真正好处。所以我们有一些数据绑定API可以帮助你将数据与前端的图形元素直接连接起来这样你就不需要编写任何样板代码也不需要处理事件或变更。至少在内部泛型会改善这一点因为我们目前是通过代码生成来实现的。然而目前我们还没有准备好采用泛型因为我们支持的Go版本比引入泛型的版本要早很多……部分原因是我希望人们能够使用他们系统上默认安装的Go版本来构建他们的应用程序。而有些系统的Go版本还没有更新到足够新的版本。我认为Debian稳定版上仍然使用的是1.15版本所以我们在等待他们的下一次发布届时可能会更新到1.18版本……
另一个原因是我们仍然支持Go 1.14 API因为这是最后一个支持苹果ARM-32设备的版本。我的内心有一部分实在不愿意因为编译器团队同意了苹果的观点而将数百万设备推向废弃堆这些设备被认为是遗留设备。
所以我们最终会做出改变当然人们也在推动这个改变因为新语言特性确实很棒……所以在今年的某个时候我们会升级我们支持的最低版本。不过即便如此我仍然不完全相信泛型会对我们的API产生巨大的影响。
Mat Ryer: 是的。LeaWails的思路也是类似的你可以绑定类型。我猜你现在是使用接口。泛型会对你有所帮助吗还是会改变你的现状
Lea Anthony: 嗯我也不确定。我觉得像Andy一样我也只是静观其变看看泛型会带来什么变化。对我来说泛型最好的用例是数据结构中的一些东西这些东西你不一定会直接处理。是的在某些情况下它确实很有用比如你想在不同类型之间重用某些功能而且你希望能够重用这些代码……但我还没有看到太多地方能用到它。我一直在考虑开发一个状态存储的概念。
我是Svelte的忠实粉丝Svelte中的状态存储非常简单和实用我有点喜欢这个想法希望能在Go中使用它作为一种桥梁。所以你会有一个通用的状态存储。我之前曾实现过一个它使用了接口空接口但存在一些问题。你需要让开发者自己处理所有的类型转换问题还要处理如果你想更改这些东西会发生什么……这不是一个好的解决方案。我想泛型可能会有帮助你可以创建多个存储存储不同的东西并且可以使用相同的代码……我还在研究这个问题这不是我花了很多时间去研究的东西。我不确定答案还没有定论。 译者注: “Svelte 是一种构建 Web 应用程序的新方法。它是一个编译器可以获取声明性组件并将它们转换为高效的 JavaScript从而彻底更新 DOM。” 上述内容来自 https://github.com/sveltejs/svelte Natalie Pistunovich: 这是个有点意外的回答因为在我听过的关于泛型利弊的讨论中很多时候正面例子都是“用户输入”我原以为GUI领域会听到两个“是的”和两个“还没有”。但你们的回答很有新意。
Mat Ryer: 是啊我们需要深入探讨一下这个问题我们要做一期Go Time的节目讨论一下泛型的现状看看它的发展情况以及人们如何使用它或者有没有滥用……这很有趣。
Mat Ryer: 如果你今天重新开始这些项目你会有什么不同的做法吗
Andy Williams: 哇我立刻想到了一些事情。我们很早就稳定了API。我们现在处于1.0版本可能是开发的第二年……很多人批评我们“太早了你不可能满足语义API保证并且持续支持下去。” 但我们成功了没有出现意外的破坏性变更。不过几年前我们确实需要引入v2包来做一些破坏性变化……所以对我来说最简单的答案就是我不会在第一次API设计时犯那些错误尽管我们花了一段时间才理解其中的原因。背后的问题是我们意识到要跨平台渲染内容的复杂性当你面对如此多样化的屏幕输出类型时像像素密度、尺寸等各种差异……
最初的问题是我以为输出类型应该是整数用来定位屏幕上的像素因为像素是比较标准的。如果我们要放大我们会遵循苹果的主张使用一倍、两倍、三倍图像来适应更高的像素密度屏幕。我们按照这个模型运行了一段时间效果还不错但后来问题开始出现了因为我们引入了一个动画API如果你使用移动动画它会将某个对象从一个位置移动到另一个位置。而当你的输出设备精度是整数级别时放大后中间的数值就不存在了。动画会跳跃、跳跃、再跳跃所以我们不得不将其改为基于浮点数的系统。我真希望当初没有犯这个错误因为这是我们必须升级的一个真正的破坏性改变。
但当你不完全理解自己进入的领域时那些复杂性会被忽视……万一有年轻的、有影响力的开发者在听不要自己构建图形工具包。这么做真的不安全还是放弃吧。
Mat Ryer: 或者如果你要做或许你的建议应该是“永远使用浮点数”。
Andy Williams: 嗯我不确定我会坚持这个观点如果我说永远使用浮点数可能有人会收回我的软件工程师执照。
Natalie Pistunovich: 我们也会从你手中拿走硬件比如FPGA。
Andy Williams: 是的。
Mat Ryer: Lea你是用整数还是浮点数呢
Lea Anthony: 很有趣Andy 提到苹果工具包时我注意到他们在很多我意想不到的地方使用了浮点数。我其实并不太明白为什么要这么做所以谢谢 Andy我学到了新的东西太棒了。
Andy Williams: [笑] 太好了。
Lea Anthony: 是的我想如果我重新开始开发 Wails… 我可能犯的最大的错误就是出于善意试图让开发者的体验尽可能简单。问题不仅在于库本身还在于围绕它的所有工具以及你试图简化的所有事情。你会遇到各种问题比如“我怎么快速启动一个项目我如何开发应用程序的某些方面我如何在运行时开发它我如何实时运行和修改它我如何实时修改 UI”因此围绕这些问题有很多工具这些工具大多是出于善意而开发的并且大多数情况下运作良好。
能够打开浏览器并使用你选择的语言或工具包的扩展这很棒。所以能够做这些事情并提供所有这些功能确实很棒。然而我要说可能 90% 的错误报告都出现在工具上而不是库本身。所以我们实际上正在考虑将这一部分功能回退一点不再让工具像一个黑箱执行你意想不到的各种操作而是将很多功能简化为独立的操作。例如如果你想转换图标只需执行一个操作。我们将使用 Taskfile不知道你是否听说过它有点像用 Go 写的 make。我们正在使用它来协调你通常会执行的所有操作。希望这能把更多的权力还给开发者让他们有灵活性去选择自己想使用的工具构建他们想要的流水线。所以回过头来看这可能是我希望能早一点做到的。
Mat Ryer: 这很有趣。我确实喜欢你对开发者体验的关注。我认为这是一个重要的教训任何构建自己希望他人使用的包的人都应该学习。因为这些开发者就是你的用户而用户体验是至关重要的。
Lea Anthony: 这关系到其他人使用你的工具时的体验这让我想到另一个我可能会做得不同的地方… 这适用于任何库---那就是尽早让更多的社区成员参与进来。不要试图自己构建一个完整的演示版本试着让大家早期就能参与进概念设计。无论他们是否在这个领域有经验或者他们是否完全是小白他们都会对你正在做的事情有很好的反馈并且可能还会帮你实现它。我们的社区实际上整个 Go 社区都非常支持并愿意帮助。所以有他们的参与是非常棒的但我认为我在早期并没有利用好这一点。我当时的想法是“我先做一个版本证明这是可行的。”
Mat Ryer: 我能理解但我觉得你说的这个点非常好。这也是一个在很多地方都适用的教训。我认为这对那些刚刚进入科技行业并想要参与某些项目的人来说也是个好消息。因为他们常常觉得“我能做什么我有什么用处” 但实际上他们的视角非常有价值。他们不知道自己的视角有多么珍贵因为有时候当你在这个行业待了很久你积累了很多知识甚至自己都不太意识到而这些知识会影响你所做的很多事情。所以如果你是新人这实际上是一种超级能力特别是当你对某些事情不太了解的时候。所以你永远不该觉得自己没用。
Lea Anthony: 再往前推一步… 这可能是---这是我第一个开源项目。我是一名软件开发者而不是社区维护者我通过一些艰苦的经历学到了如何处理开源项目的一些方面。我认为如果你要开始一个开源项目有一件事你应该尽早确定那就是如何进行互动。如果你想要一个新功能或者你想报告一个错误应该有一个明确的流程。因为获取所有这些意见是一把双刃剑。一方面它带来了一些非常好的创造力但你也需要设置一些边界和指南来管理这个过程因为你不可能接受所有东西你不会接受每个人的想法。你会认为有些想法很好有些则不然。所以你需要有一个框架来管理这一切否则你的项目可能会走向奇怪的方向最终变得难以维护或者你可能会为某个极端情况开发出非常特定的功能。我不知道 Andy 你是怎么处理这些问题的但对我们来说这一直是一个挑战。
Andy Williams: 你说得对这确实很难但也非常重要。而且不是每个人都会很开心尤其是当他们的建议没有被采用时。不幸的是事情有时会变得个人化。因此我认为非常重要的一点是讨论想法或概念时尽量与提议的人区分开来。如果你有两三个人在讨论某种方法的利弊请确保你是在描述和讨论这个想法而不是提到“这是某个人提出的”。这样你就可以避免让讨论变得个人化。
除此之外正如你所说仔细定义这些流程---社区指南、贡献者指导---这样当你不得不拒绝某些建议时你可以说“因为这些原因它不符合我们的做事方式。” 我有一个原则适用于核心贡献者和首次贡献者如果我们找不到一个明确的规则或指南来解释我们为什么不接受某个提案那么说明我们的规则需要更新。接受某些东西或拒绝某些东西绝不应该是主观判断。应该是“质量不够因为我们期望达到某个标准”或者“这个 API 不符合我们的设计风格因为我们是这样设计我们的 API 的。” 这确实能帮助我们。
这种方式不一定在每个情况下都适用有时候你可能会有自己的一些偏好尤其是作为维护者或创建者的一部分。你可能会觉得有更好的方法或者你脑海中已经有了一个计划。但在这种情况下你可以帮助贡献者让他们的代码更符合你认为的未来方向。这种情况并不常见有时它略显主观但你可以说“因为我们计划做的另一件事它可能会与此冲突。因此我们能不能找另一种方式来探索这个问题” 通常人们能理解这些因为他们并不了解项目的所有规划。但即便如此你分享得越多他们就会越少感到惊讶贡献也会更有方向性。
Mat Ryer: 那么关于个人品味的问题呢Andy有时候选择并没有对错之分但你只是更喜欢某种方式。你是怎么处理这种情况的
Andy Williams: 我认为这归结于达成共识社区有某种偏好并且这些偏好被记录下来了。当然如果我们是一个较老的项目使用的是一个不那么先进的语言我们可能会讨论“应该用 Tab 还是空格” 但我们已经摆脱了这些纠结因为大家都同意 Go 的格式化标准是正确的。老实说我不认为 Go 代码的格式是我以前喜欢的格式但我也不太在意因为这是写 Go 代码的标准方式。如果你能把所有主观的东西都这样表达出来比如“这就是我们社区的规则这是贡献的规则。如果你不喜欢我们完全理解…但请按照我们的方式来否则我们将退回 PR。” 因为老实说接受某人的工作然后修改以适应项目的标准这是一件很糟糕的事情。首先这会给核心项目的成员增加额外的工作。而且我听说有些贡献者会因此感到沮丧因为他们提交的东西被立即修改了他们会觉得自己的工作被质疑了或者没有达到他们事先不知道的更高标准。
Mat Ryer: 有趣。嗯你经常需要说 “不” 吗
Andy Williams: 是的… [笑] 不过我会尽量说“因为某些原因所以不行”或者如果可能的话我会说“我在某个地方有疑虑”这样就不完全是否定但也不是肯定。
Mat Ryer: 很外交的回答。
Andy Williams: 当你有这么多白发时这种情况遇得多了你也就学到了这些经验。社区中有一位我合作过多年的朋友他曾对一个新人描述我带领的项目时说“你知道的可能会有一些看似难以接受的反馈但它们是经过深思熟虑的理解它们很重要。如果你愿意接受这些指导并更新代码以适应项目你会被社区接纳。如果你不愿意那你可以维护自己的分支或者为另一个社区贡献或者保持自己的项目。” 有些人确实这么做了这也是开源的美妙之处---你可以在核心社区中也可以在它的旁边维护一个分支或者一些其他人可以使用的组件。你不一定要完全赞同一个社区的结构。
Mat Ryer: 这很好。Lea我觉得你可能更直截了当。
Lea Anthony: [笑] 你为什么这么说
Mat Ryer: 因为我了解你。
Lea Anthony: [笑] 不这确实很难。就在最近有人提交了一个 PR但没有先开 issue而且这个 PR 更像是个人偏好的修改。最后我不得不说“我们可能不会在这个版本中加入这个功能。这是一个有意思的想法但这也是我需要维护的内容而很多 PR 的一个常被忽视的方面就是谁来维护它。所以我建议你可以在自己的分支上运行这个修改并使用它。” 正如 Andy 所说这就是开源的美妙之处。你不会被项目的方向或意见所限制你可以选择按照自己的方式行事这完全没问题。
Andy Williams: 我记得有一次和另一位优秀的社区领导者的对话当时我刚开始 Fyne 项目我说“我们要有一个干净的 API。每个人都可以轻松上手并构建自己的应用程序。我们会添加很多新功能开发应用程序从未如此简单。” 他看着我说“好吧听起来你有一个很好的开始。但十年后再回来告诉我你的 API 是否仍然像现在一样简单。” 所以有时候拒绝某个功能的原因只是“这超出了我们想要实现的范围。” 不过因为这是一个更广泛的社区你可以有插件、附加组件或者是与主项目并行的功能。我们在 Fyne 中已经开始这样做了我们有一个扩展库就像 Go 语言一样。这是一个很好的模型运作得很好。所以一些可能是未来的一部分的功能目前可以放在主项目之外。正如 Lea 所说我们专注于核心团队愿意长期维护的功能。
Lea Anthony: 这也是我们在第 3 版中采用的方式---插件系统让人们可以开发自己的功能。
Mat Ryer: 是的特别是当建议通常不是疯狂的想法时。这些想法是合理的。有时候如果你能在“用户空间”解决问题虽然可能工作量会大一点但有时候这就是答案……我们倾向于专注于启用这种功能而不是把每个功能都添加到工具包中。我有一个小小的项目---你之前提到了 Testify我很感激……
Natalie Pistunovich: 节目笔记……
Mat Ryer: 节目笔记……到现在也不需要再提了吧我们还是提一下吧。
Lea Anthony: 什么是 Testify开个玩笑Mat。[笑]
Mat Ryer: Wails 用什么
Lea Anthony: Is。
Mat Ryer: 是的我正要……
Lea Anthony: 你听说过吗
Mat Ryer: 是的我正想说 Is。这个想法来自于 Testify 的迷你版本。它的目标是拥有最小的 API。Testify 的 API 很庞大因为它希望尽可能简化测试的编写和阅读所以我们添加了很多功能。我不知道我们是否有关于哪些 API 被使用的数据……但如果有那会很有趣。你可能可以编写一些工具来跟踪人们使用了哪些 API。我得研究一下。
总之Is 的想法是 Testify 的精简版只有一个很小的 API。这个项目收到的 PR 主要是关于添加一些常见的功能但你可以使用 is true并在里面放入任何表达式。这样你就能在测试代码中解决很多问题而 Is 的 API 保持较小的规模。这通常是我们更喜欢的方式。但这也是一个艰难的对话因为人们提出的想法和贡献通常都很棒但有时与项目的目标不符。所以我认为你说得对明确项目的使命以及它遵循的原则非常重要。
Andy Williams: 我完全同意这个观点关于可扩展性的概念。如果人们可以自己构建某些东西它可能以后会被添加进来但至少它不会阻碍他们现在的应用程序开发。我们试图让现有的组件在一定程度上是可扩展的。我们不希望因为这个而让它们变得复杂但你可以进行扩展。关键是我们并没有使用原生组件我们自己绘制所有组件。我们标准包中的所有组件都是使用与所有人都可以访问的公共 Canvas API 构建的。
所以如果你想做些不同的事情完全可以在自己的代码中实现。这可能不会只是几行代码因为你是在做非标准的事情但它确实帮助了一些企业客户他们可能会说“我们必须这样做”或者“我们必须添加这个功能。” 通过一些帮助他们就能在自己开发的自定义组件中实现这些功能否则他们可能会停滞不前。
Mat Ryer: 好的。现在是时候了Natalie你知道现在是什么时间了吗
Natalie Pistunovich: [唱歌] 这就是它的延续……
Mat Ryer: 是的大家准备好吧。现在是“不受欢迎的观点”时间
Mat Ryer: 哇真让人精疲力尽。Lea你有什么不受欢迎的观点
Lea Anthony: 我今天的不受欢迎观点是最适合的工具并不总是最适合的工具。
Mat Ryer: 什么
Lea Anthony那么我的意思是什么呢……是的这个观点会有多不受欢迎呢……
Mat Ryer[笑] 是啊说某样东西不是它本身这肯定会非常不受欢迎我想。
Lea Anthony可以说是有争议的。作为工程师我们总是试图使用最适合的工具来完成工作因为我们想做一份出色的工作。然而如果你是在为自己的时间付费那没问题。但如果是别人为你的时间付费那么你设计的工具是否是整体上最适合的工具呢我最近通过一篇文章意识到了这一点文章的作者我现在记不起名字了。他基本上讲的是他有一个新来的经理他们想要实现---我不太记得是个什么东西了可能是一个队列之类的。于是他们就说“哦那我们去用 Kafka 吧”或者类似的为这种任务设计的技术。
Mat Ryer哦我还以为你说的是台球杆呢。
Lea Anthony哦我非常喜欢台球非常非常喜欢打台球。我们可以聊聊这个。
Mat Ryer你游泳吗
Lea Anthony我游泳。我有个游泳池所以还不错。
Mat Ryer真的吗你有台球桌吗
Lea Anthony没有我应该买一个。
Mat Ryer你真的有游泳池吗
Lea Anthony是的我旁边还有一张桌子但我想这不是你想问的吧
Mat Ryer不我觉得你得把桌子放进池子里才算数。
Lea Anthony好吧我待会儿发张照片给你。
Mat Ryer住在澳大利亚的人都有游泳池这太疯狂了。好吧抱歉打断你了……
Lea Anthony没关系我刚说到哪了哦对了新经理来了之后问“你们现在用的是什么”我想他们当时用的是 Postgres 或类似的东西。然后经理说“对于这个用例让我们用 Postgres 来实现吧。” 工程师们当时都觉得“你在说什么这太疯狂了。” 但他们还是这么做了。之所以这是个好主意是因为这是他们完全理解的技术他们有所有的控制手段如果出了问题他们可以应对。基于他们的用例Postgres 完全足够了甚至比他们需要的还要多。所以尽管它不是最适合的工具但它确实是最适合的工具。这是我最近学到的一个有趣的东西。
Mat Ryer是的我对此非常感兴趣。我还想说在这个例子中除了他们熟悉 Postgres 之外还避免了引入新的技术。所以维护和操作的东西也减少了这也非常有价值。我认为我们经常犯的一个错误是忘记了维护的重要性因为我们通常把它看作是开发和部署以及添加新功能的背景噪音往往会忽略它。但实际上尤其是对于那些成功的项目维护的成本通常远远超过了最初的开发成本。而且简化基础设施也是一件好事。所以我很认同这个观点。我在想这个观点会有多不受欢迎呢
Andy Williams不错。是啊。
Mat Ryer还有其他观点吗
Andy Williams是的我有一个不受欢迎的观点可以分享……
Mat Ryer哦那请讲。
Andy Williams我今天的这个不受欢迎的观点是---我原本不知道这会是不受欢迎的但之前我提到过我们在 Go、Fyne 和 Wails 等社区里有一个很棒的群体。我们非常幸运地有一些赞助商帮助我们推动项目这和 Go Time 以及其他一些很棒的地方是一样的……不过我一直在寻找一些方法以便让项目能够在未来得到更多的支持扩大它的影响力。这时我意识到也许并不是所有人都同意我的看法。我的观点是开发者会为了一个有用的工具包去学习一门新的编程语言。我原以为大家会选择合适的工具并且会为了这个工具去学习相应的技术。一旦你学会了两三门编程语言再学一门其实也不是什么大问题尤其是像 Go 这样在语法上非常熟悉的语言。所以我非常有信心人们会为了使用这些优秀的新图形应用技术去学习 Go。但是似乎有些人并不这么认为他们觉得这样做有点冒险。所以这就是我今天的不受欢迎的观点。
Mat Ryer我们会在我们的 Twitter 账号 gotimeFM 上测试这些观点然后告诉你Andy看看到底是不是真的不受欢迎。但这很有趣。我肯定会这么做。我肯定会为了使用某个工具去学一门新语言。事实上我还挺喜欢学习新语言的当然是编程语言。毕竟我是英国人不会说其他语言。我们英国人真是傻。所以我挺喜欢学习新语言。**我有时候还会怀念技术困难的那些日子。当一件事变得简单时我反而会失去一点动力。我喜欢那种困难时期的推动力当你无法解决问题时你会有那种干劲。所以我挺喜欢这种感觉的。**不过这确实很有趣。不知道大家有什么看法
Natalie Pistunovich我尝试了很多编程语言或者让 AI 编写一些东西所以我几乎看不到尝试新东西的障碍。比如用这门语言写这个东西或者使用这个工具包。也许做个基准测试会很有趣。[笑] 这几乎和你说的相反Mat你经历了学习和尝试新语言的艰难过程而我慢慢开始看不到这种学习的好处。
Mat Ryer是啊。我并不是说这样做有什么好处……事实上我做的大多数事情都没有什么好处。
Natalie Pistunovich如果是为了好玩那当然可以100%支持。
Mat Ryer是啊。那么你会让 AI 帮你写代码吗
Natalie Pistunovich是的。
Mat Ryer这不算作弊吗
Natalie Pistunovich我不确定。你在 IDE 里用过任何插件吗你用过代码补全功能吗
Mat Ryer不没有……
Natalie Pistunovich没有你用的是纸和笔。[笑]
Andy Williams他是用穿孔卡片来编程的。
Mat Ryer我会喜欢那样的。是啊我怀念技术还很糟糕的那些日子。我怀念那些年……
Natalie Pistunovich那就别用 Go 了。[笑]
Mat Ryer该转向 Java 了。抱歉Java 开发者们……不过我想 Java 开发者不会听这个节目吧我不知道。
Lea Anthony可能有些前 Java 开发者会听。
Mat Ryer嗯他们会被冒犯吗
Lea Anthony可能不会但谁知道呢。
Mat Ryer可能不会。是啊。无论如何Natalie当你辅导初级工程师或刚入行的人时你会鼓励他们学习其他语言吗
Natalie Pistunovich我一定会鼓励他们学习一些概念比如设计模式。设计模式、算法这些跨越所有语言的东西你一定要知道。语言只是实现好点子或概念的工具或者是实现可复制的东西的工具。所以那些能够跨语言的东西你应该掌握。至于具体的语法我越来越觉得它不那么重要了。这可能不是个不受欢迎的观点尽管它有可能是。
Mat Ryer我们拭目以待。我不确定。不过你确实有一个不受欢迎的观点……
Natalie Pistunovich我有另一个不受欢迎的观点。我在想我之前说的那个是否也算作一个不受欢迎的观点。我得在另一期节目里试试。不过在这一期里我的不受欢迎观点来自我们在录制前的技术测试当时我们讨论今天是春分日。在一些语言中“天”这个词有不同的含义既可以指从午夜到午夜的24小时也可以指白天的日光时间。英语中没有这种区分。我很好奇这有多不受欢迎但我觉得在这个方面我们错过了一些东西。我们应该有两个单独的词来表达这两个概念。
Mat Ryer是啊不过……有时候你可能会说比如我问你“现在是白天还是黑夜” 如果我这么问你我想……
Natalie Pistunovich我会很困惑。这是在问24小时的时间段还是在问白天
Mat Ryer对那确实是个奇怪的问题。就像问“你想要食物还是一个汉堡” 这挺让人迷惑的。
Andy Williams尤其是---如果你有窗户可以很容易地回答这个问题。不是汉堡那个抱歉是白天还是黑夜的问题。
Mat Ryer你是说通过看窗外。
Andy Williams没错。
Mat Ryer是啊。那么Natalie你能举个例子说明哪种语言有这种区分
Natalie Pistunovich希伯来语。
Mat Ryer那这两个词是什么
Natalie Pistunovich: 从午夜到午夜是 Yemama而从早晨到傍晚是 Yom。
Mat Ryer: 哦听起来挺酷的。不过我不觉得这对我们有什么影响。就像我从来没有注意到---你懂我的意思吗我从来没有---
Natalie Pistunovich: 因为在你的脑海里这两者是一样的。但我确实注意到了。我现在回忆不起具体的情况但我记得有过一些场合我在想“为什么为什么要丢掉这个概念”
Mat Ryer: 太神奇了。
Natalie Pistunovich: 尤其是英语有那么多词汇来描述许多类似的事物。
Mat Ryer: 是啊但我们就是没在意这个。我有一个不太受欢迎的观点。我觉得这个观点可能会让一些人生气……希望不会但也希望会。我的不太受欢迎的观点是 Wails 的 logo也就是 Wails 应用的 logo 是世界上最好的应用 logo。如果你还没见过这个漂亮的红色龙…… Lea这背后有什么故事吗
Lea Anthony: 嗯我希望我能说这是我设计的。但我的设计水平跟两岁的孩子差不多所以我得外包出去。最初的 logo 是我看到的一种纹身风格的设计---你知道那种纹身风格的龙吧……最初的原因是它看起来有点像亚洲风格同时还保留了和 WAILS 龙的联系。而到了第二版我想“你知道吗我想要一个非常有冲击力的 logo。这是一个大版本发布我想让它变得更大更特别一些。”
所以我四处打听我在 Twitter 上发帖问“有人认识设计师吗” 结果---噢千万别这样做。天哪你会收到一堆乱七八糟的回复就像你在说你有一份年薪 30 万美元的工作一样。你会收到太多的回应。其中有个人发了他的作品集给我真的很棒。我想“这家伙可能超出我的预算了。”但我们聊了几句来回讨论了一下然后他就设计出了这个很棒的 logo。我当时就觉得“是的我基本上不需要改什么了。这太有冲击力了。” 真的很棒。所以是的这就是这个 logo 的故事。我开始使用它后收到了一些很好的反馈。不过遗憾的是这不是我设计的。但确实是一个很棒的作品。
Mat Ryer: 没错真是个棒极了的作品。我们还得提一下威尔士的国旗---它可能也是世界上最好的国旗。我不想展开这个话题---
Andy Williams: 我觉得它得到了投票认可。
Mat Ryer: 旗帜确实需要投票所以这很好。
Andy Williams: 呃…… [笑声]
Mat Ryer: 你们都见过威尔士国旗吗Natalie你见过威尔士国旗吗
Natalie Pistunovich: 我现在正在谷歌搜。
Mat Ryer: 搜一下你不敢相信。
Natalie Pistunovich: 我可能见过但我现在要搜一下。
Mat Ryer: 我们会在节目注释里放一个威尔士国旗的链接。你不会相信这是真实的国旗。它是真的。
Natalie Pistunovich: 我喜欢这条龙。它也是一条红龙走在草地上天上是一片纯白的天空。
Andy Williams: 是的那是云。
Mat Ryer: 为什么是白色的
Natalie Pistunovich: 那天有点多云。
Mat Ryer: 就是个晴天对吧
Natalie Pistunovich: 那是雾。
Mat Ryer: 水旗。好的很遗憾我们今天的时间到此为止了。非常感谢你们。这次我们学到了很多关于 Fyne、Wails、跨平台编码、开源社区和开源项目管理的内容……Andy Williams非常感谢你。顺便说一下我很喜欢你制作的配乐。我知道你做了《侏罗纪公园》的配乐。那真是一首经典曲目。
Andy Williams: 太好了简直不敢相信。你得把所有这些东西混合在一起。毕竟创造力是软件工程的重要组成部分。
Mat Ryer: 是啊。斯皮尔伯格是什么样的人
Andy Williams: 说实话他没我想象的那么多时间来关注我尽管我在新闻里读到我们关系挺近的。
Mat Ryer: 真可惜。真是太可惜了。
Andy Williams: 也许我们可以再联系一次试着让他参与下一次 GopherCon看看能不能一起做点什么。
Mat Ryer: 我觉得开场的视频效果会很棒不是吗
Andy Williams: 绝对的。实际上我已经迫不及待想看到它了。我们赶紧搞定吧。
Mat Ryer: 完全赞同。Lea……
Lea Anthony: 嗨
Mat Ryer: Lea Anthony。哦这原本是个结尾部分。
Lea Anthony: 你好。
Mat Ryer: 不别说你好了。现在是告别部分了。
Lea Anthony: 啊……但我真的不想告别。我真的玩得很开心。
Mat Ryer: 这是个好借口因为……
Lea Anthony: 是啊。
Mat Ryer: 这段肯定会被剪进去。你说了这句话肯定会被剪进去。
Lea Anthony: 可以把这当作我的不太受欢迎的观点吗 [笑声]
Mat Ryer: Lea Anthony 来自 Wails 和 Wails 项目Andy Williams当然还有 Natalie Pistunovich非常感谢你们。下次见Go Time 节目再会