Keyboard maestro 当中,如何实现获取当前选中文字?

在使用 Keyboard maestro 的过程中,可能你需要实现对选中文字进行特定的操作,这个时候你可以选择配置如下的宏

具体实现思路:

  1. 执行 Ctrl + C 执行复制(将选中内容放在剪贴板里)
  2. 执行 Delete 执行删除(将选中内容删除)
  3. 插入新的文本(并将系统剪贴板的内容作为变量放在里面)。

论坛当中还看到另外一个解法,感兴趣的可以试试看

Keyboard Maestro 如何配置只在某个应用程序中生效的宏

在 Keyboard Maestro 的配置过程中,你可能希望某些命令只在特定的程序内生效,这个时候你可以选择将这些宏放置在一个特定的 Groups 里,并编辑这个 Group,设定 Group 为 Available in these applications:,并在其中选择你要生效的应用程序,就可以实现某些特定的宏只在对应的应用程序中生效,避免你定义的宏和其他应用程序冲突。

black and silver laptop computer

如何找到使用 Secure Input 的应用

我在写作时,会使用 aText 来做大量的文本替换,以提升输入的效率。但在 macOS 下,aText 常常会被 Secure Input 所阻塞,无法使用。这个时候你需要找到正在使用 Secure Input 的应用,并关掉它,不然你的 aText 始终无法启用。

想要找到它也非常简单,你可以执行如下命令,来查找开启了 Secure Input 的应用

ioreg -l -w 0 | grep SecureInput
执行效果

找到对应的输入后,可以看到 kCGSSessionSecureInputPID 的 PID 值,比如我这里是 182,接下来可以执行如下命令来找到 PID 为 182 的程序到底是哪个

ps auxww | grep 182 #你在使用的时候,记得替换为你对应的 PID 

执行后可以看到红框的部分就是 182 进程。我这里是 macOS 自带的 Login Window。Login Window 只需要对系统执行一次锁屏 & 解锁,即可解开 Secure Input。如果你的是其他应用程序,则可以直接使用 kill PID 来关闭。

延展阅读

Internal Bleeding printed paper

《省钱女王:如何享受极简生活》书摘

这本书里面是各种小技巧,如果你打算降低自己的开支,可以看一看

  • 我的原则如下: 第一,每项常规支出越少越好。 第二,不要增加开支项。
  • 节俭也要有底线。节俭是为了生活得舒适,不是委屈自己。就好比走钢丝,我们要平衡好两边,才不会摔跤。不打破底线,才是适度的节俭。
  • 如果你对传授经验不感兴趣,可以考虑用别的方法创造被动收入 1 和固定收入。你要是真心想改善自己的财政状况,我推荐你读这两本书:《百万富翁的快车道》(The Millionaire Fastlane )和《网络兼职指南》(Where to Work Online)。
  • 工作保障压根儿没有 保障,它不过是一连串的空口诺言,只是为了让员工们低眉顺眼任劳任怨而已。在这个国家,真正有保障的,是那些自力更生的人。
  • 如果你想买什么东西,先想想,使用这样东西要用到的辅助工具是不是还需要另外购买。
  • 如果你想看看你开始或重新开始极简生活要买的最少物品的清单,可以查看电子书《如何开始或重塑极简生活》( How to Start Out or Over on a Shoestring ) 。
  • 不要为了省钱而做蠢事。 比如说,如果你确实需要一台冰箱,那就买一台小冰箱吧。
  • 不要拣了芝麻丢了西瓜。
  • 计算省下的钱时,要把时间也算进去。
  • 传真机。 我用Faxzero.com免费发传真。但如果我想把 调制解调器连接到电脑上,Windows 7也能够通过传统的电话线收发传真。以前我甚至还通过调制解调器用魔术杰克收发传真;现在,我要求别人用电子邮件的方式发文件给我,这要方便得多。
  • 如果你在用微软Windows系统,不妨去Waysale.com淘自己需要的软件,这一选择合法又实惠,可以为你省钱。我在这个正规合法的网站更新已有的Windows和办公软件,并获取其他需要的软件。
  • 你可以在网上找到海量电子书。在线电子书零售商会免费提供许多书。多年来,我从古登堡计划(Project Gutenberg)上获得了很多免费电子书资源。澳大利亚的古登堡计划上有各种各样的书籍。如果你在找一本古董级图书,不妨在这两个网站上试试。 谷歌图书(Google Books)和互联网档案馆(Internet Archive)都有可供查询的大量档案。如果你在研究灵魂课题,可能会借助于Sacred Texts Archive。这些网站有大量可以在线阅读的书籍,同时也是新思维(New Thought)书籍的绝佳来源,其作者包括华勒斯·瓦特斯 ( Wallace Wattles )、 罗伯特 ·科利尔 ( Robert Collier )和 佛罗伦萨 ·斯高伏尔·西恩 ( Florence Scovel Shinn )等人。FreeEbooks.net和ManyBooks.net是我最近发现的两个免费提供电子书的网站。不花一分钱,常年有书读。我在参考资料部分列出了所有这类网址。
  • 雷格列表 http://www.craigslist.org 和自由交换网 http://www.freecycle.org 都是网上买卖物品的好去处。
  • 阅读关于水的文章——《水:为了健康,为了治愈,为了生命:你不是病了,你只是渴了!》(Water: For Health, for healing, for Life: You’re Not Sick, You’re Thirsty! )更多信息,请关注F·巴特曼博士。你还可以登录Watercure.com去关注更多该作者的信息。
  • 多莉·弗里德在她的书《袋鼠式生活》(Possum Living )中对饲养动物以获取肉食这一行为,发表了深入的见解,我向所有感兴趣的人强烈推荐此书。
  • 阅读拉格纳·本森的著作《自助用药》(Do It Yourself Medicine ),书中介绍的获取处方药的方法一定会让你大开眼界。
  • 同时你还可以访问西方基金会的下载页面阅读关于健康的免费电子书。特别推荐两本书:《没有医生的地方》(Where There Is No Doctor )以及《没有牙医的地方》(Where There Is No Dentist ),由西方基金会制作 http://hesperian.org/books-and-resources/ .
  • 我一直在寻找关于老式家庭疗法的书籍,我最喜欢的后备书是詹姆斯·杜克的著作《绿色药房》(Green Pharmacy )。
  • 关于牙齿保健详情可下载由西方基金会(Hesperian Foundation)制作的免费电子书,《没有牙医的地方》(Where There Is No Dentist
  • 有个博客里面有自己修剪头发的介绍。详情请参阅 http://feyeselftrim.livejournal.com/ 。
  • 更多清洗秘诀可查阅《极简主义的清洗方法》( The Minimalist Cleaning Method ) 。可在参考资料 部分找到有效链接。
  • 免费电子书: http://www.gutenberg.org/ http://gutenberg.net.au/ http://books.google.com/ http://www.archive.org/index.php http://sacred-texts.com/ . http://www.free-ebooks.net/ http://www.manybooks.net/
  • 西方基金会(保健医学及预防医学方面的免费电子书和资料): http://hesperian.org/ 车轮上的无家可归者 http://homelessonwheels.wordpress.com/ 《如何开始或重塑极简生活》 (How to Start Out or Over on a Shoestring) 安妮·珍·布鲁尔著 http://www.smashwords.com/books/view/69709 《如何一无所有地生活》( How to Survive on Practically Nothing )爱德华·H·罗姆尼著 《没有工资如何生存下去》( How to Survive Without a Salary )龙雅各著 《如何写作及出售电子书》( How to Write and Sell an Ebook ) 安妮·珍·布鲁尔著 http://www.smashwords.com/books/view/36647
  • 《穷理查德的年鉴》( Poor Richard’s Almanack )理查德·桑德斯(本杰明·富兰克林)著 《若无其事的生活》( Possum Living )多莉·弗里德著 多莉·弗里德的故事: http://www.paige-williams.com/ 马铃薯栽培: http://www.poconogardening.com/potato.html http://gardendesk.blogspot.com/2008/10/garbage-can-potato-harvested.html 《质朴:最佳简易家装书》( Simplicity: Simply the Best Home Decorating book ) 介绍制作窗帘等家居装饰品的完美资源。 塔米·斯托罗贝尔所著的简化无车生活:回顾版 http://www.associatedcontent.com/article/5756060/simply_carfree_how_to_pedal_toward.html?cat=38 微软操作系统的软件(非常便宜): http://www.waysale.com/softwares
  • 《本杰明·富兰克林自传》 ( The Autobiography of Benjamin Franklin )本杰明·富兰克林著 《极简主义的清洁方法》( The Minimalist Cleaning Method )安妮·布鲁尔著 http://www.smashwords.com/books/view/35019 《节俭生活的地下指南》( The Underground Guide to Living Frugal )比约恩·卡尔格著 《财富之路》( The Way to Wealth )本杰明·富兰克林著
Internal Bleeding printed paper

《职场奋斗记》

这本书我看了一半以后看不下去了,主要的原因是太水了。当成传记看还行,别的没必要。

  • 每个人的一生中至少要证明两能能力:获得机会的能力与建立在这种能力之上的工作能力。
  • 实际情况是,一个人的家世背景在职场上起着举足轻重的作用,但这一作用的值是中性的,如果你立得正,行得端,这一值就会是个正数,就会帮助你比别人更容易成功。反之,如果你的行为有差池,做出了有辱家族名誉的事情,那么,这个值就会成为一个负数,值数越高,负面效果也就越明显,所引发的职场动荡与冲击也就越猛烈。
  • 人在职场,你必须要时刻记住为自己说话,如果你不说,别人就更没有这个义务。
  • 人生最可怕的事情,就是命运已经注定。 因为人是靠希望而生存的,未知与不确定性会激发人最大程度的奋斗欲望,一旦失去了这些,人的生命价值就会降低,生存的意义也无从谈起。
  • 命是规律规则,命是这个社会中无计其数的人相互博弈时所产生的利益推动力量,没有人能够掌控这种力量,你最多只能适应它。
  • 你要想通过一条决议,最好的办法就是在会议上突然宣布,由于事发突然,除非与会者之中存在着进退同一的反对者团体,否则,一般情况下,绝大多数人是反应不过来的,忙乱之际无法组织起反攻,等他们阵容拉起,事情已经拍板了。
  • 所谓面试,就是你通过自己的表现要让对方对你由衷钦佩的过程,任何一个招聘者都不可能对那些缺乏信心的求职者产生好印象的。
  • 在这个社会里,越是处于底层的人,越是卖力的苦干,因为那是他们唯一的立身之本。而许多熟谙社会游戏规则的人,却全不管这些麻烦事,他们知道底下人肯定会为了糊口而拼命干的,所以他们只管捞自己的,如果遇到捞得过凶的上司,下面的人多半还会出一个两个的劳模,因为劳模把贪官应该操心的事情全都承担了。 凡是出劳模的地方,必然有着许多贪官,只有贪官才需要劳模替他们卖命,老百姓是不需要这玩艺的。老百姓需要的就是各司其职,各就其位,一个关系理顺的社会,胜过一万个“英明的领导”。
  • 你必须为你自己的位置负责,这才是现实的真理!
  • 我的人生经验告诉我,人在职场有三个阶段。第一个阶段是先做事,再做人。概因一个初入职场的人,不仅对职场的游戏规则一无所知,更有着许多实践知识需要掌握,这功夫只要能够闭着眼睛把事情做下来,就已经很难得了。过了这个阶段,等到你已经掌握了足够的实践知识,能够在工作之中做到游刃有余了,就可以上升到即做人,也做事的阶段,这时候不仅要把事情做好,还要做到方方面面都满意。而到了第三个阶段,就是只做人,不做事了,这一阶段的成功者比比皆是,相信每个人自有体会。
  • 据我的观察,越是不承认组织系统内部存在着分歧的企业,其权力博弈的规则越是混乱,越是缺乏规范与自制
Internal Bleeding printed paper

《职场精进之路》书摘

  • 锦囊二:要针对岗位招聘要求有针对性地调整简历。有些面试者不管应聘什么公司或什么岗位都是通用一套简历,其实这样是有问题的。有些岗位虽然职责相似,但是要求肯定不会完全一样,有些公司是不同的行业,那么简历的表达、突出的侧重点也最好不一样。这里所谓的针对性调整简历不是刻意捏造工作经历,而是尽量突出符合岗位要求的项目经验、技能。比如,如果是一家互联网公司,你如果之前有过互联网公司的工作经验就可以多写一点,如果做过跟该公司类似的产品就可以详细一点;如果是一家外企,可能就要附上英文的简历。
  • 锦囊三:提前了解应聘企业和用人部门。现在网络这么发达,你过两天就要去面试了,总要了解一下应聘企业的情况,包括企业的规模、发展历史、主要的产品、市场份额、企业文化、主要的竞争对手等。尤其是该企业的主要产品功能、特色、优劣势,一旦面试中涉及,你可以对答如流,那么肯定能有加分,面试官也会知道你做了充分的准备。假如能有一份产品评测或体验报告会更好。即便面试过程中面试官没有涉及相关的问题,你也可以在面试结束后主动提起。如果可能也可以想办法了解一下用人部门的情况,网络上还有些大公司的面试经验,虽然这些作用不大,但是有备无患。
  • 锦囊四:提前准备好可能会遇到的问题的
  • 有句话说得好——学历是铜牌,能力是银牌,人脉是金牌,思维是王牌。
  • 但是如果工作几年之后再选择,一个成长型的小公司、有潜力的创业公司,加上好的工作岗位和股份期权也不见得就比大公司差。
  • 一份工作的投入包含多个方面,时间只是其中一个方面,还应该包含身心和知识经验上的投入。
  • 身心上的投入是指一种更加主动的工作态度,积极解决难题、跟他人合作、主动发现问题、承担更多的责任。
  • 永远不要觉得自己的付出白费了,很多时候只是暂时没有反映在待遇上,随着时间的推移,你之前的付出会形成加速度,使你的提升变成一道上升的弧线,会逐渐跟那些匀速的直线拉开距离。当你真正可以用知识、经验来工作的时候,比如一些公司聘请的顾问、专家,那么即使工作时间少,你的收入也不会少。所以在刚参加工作的这几年里,别总想着拿多少钱干多少事,这样的思想只会害了你,这是你快速积累获得加速度的时期。就如同存钱,你开始得越早,哪怕数额小一些,但是复利的力量会最终给你合理的回报。
  • 老板为什么要招实习生?道理很简单,就是要用相对廉价劳动力然后做这些琐碎的事情,把更重要的事情留给公司骨干甚至自己去做,让他们不要为这些小事分心,这样才能创造更多的价值。企业就是讲究分工的,本来就不是人人平等的。强调工作分工上人人平等,而不是根据能力经验分工的公司估计也做不长久。
  • 如何定义责任?责任至少要包含工作内容复杂度、压力和承担的风险,这三点至少要符合两点才能说明你目前岗位上的责任较大。
  • 作为职场新人,不断提升自己,能够承担更多的责任,帮助团队达成更高的业绩是重中之重。如果你始终在上司眼里像个孩子,无法担当大任,那么你的待遇肯定上不去。
  • 大部分人都是期望享受慢生活,有情有调,每天完成了自己8小时的工作,然后所有的时间都是回归家庭或者做自己想做的事情。
  • 十二年的工作经验告诉我,这个世上没有鱼与熊掌可以兼得的好事,同一时间只能选择一个。但是,你可以在你能抓鱼的时候拼命抓鱼,这个时候就先忘记熊掌,当你有了足够多的大鱼后,再拿大鱼去换熊掌。
  • 大部分时候你并不需要像电影中的情节那样去给人答疑解惑,只需要表现出自己的真诚,而不是封闭自己,甚至觉得自己跟环境格格不入,相信很快就能融入团队。
  • 善于抓住机会是在做好自己本职工作的前提下,把分配给自己的工作先做到最好,然后再看自己可以承担什么样的团队工作,或者帮上级解决头疼的问题。而不是自己手头上的工作都还没做好就去想着表现自己,这是本末倒置的做法。
  • 任何时候,当上司需要你的时候,你能马上有反应是一个好习惯。没有这个习惯,许多机会也会跟你擦肩而过。不要总觉得上司是有工作才想着你,当有好处的时候他也会第一时间想到你,而不是想到那个总是装聋作哑的人。
  • 在低价值的事情上耗费的时间越多,产生的单位价值就越少,从资产累积的角度来说就越慢。所以,不用去纠结自己是不是要买车,也不用考虑买车养车的花费,而是要好好思考一下你究竟是特别需要一辆车装点脸面还是自己开车真的给工作生活带来了十足的便利。
  • 工作的第一个维度是“岗位”工作
  • 工作的第二个维度是“通用”工作
  • 工作的第三个维度是“流程”工作
  • 工作的第四个维度是“辅助”工作
  • 学习成长从来都是一个自我对抗的过程,能速成的都不是什么了不起的内容。因为大部分人的智商都差不多,你能速成别人也可以。能让你真正领先于他人的知识不可能轻易就被获得,所以别把那些速成当宝典,你不需要速成,你需要的是专注。
  • 主动工作的人永远比被动工作的人提升快,因为主动工作的人会积极发现问题、寻找方法、攻克难关,不断得到成就感,而被动工作的人则是排斥困难,等待被安排工作,并没有想着如何做得更好,从而使自己得到提升。
  • 作为新人,“You are nobody”,做一切你可以做的事情,并且尽可能地做好。
  • 学习敏锐度高的人在五个关键要素中表现突出:自我认知、心智敏锐度、人际敏锐度、变革敏锐度和结果敏锐度。评定一个人的学习敏锐度能帮助面试官、管理者和HR做出明智的聘任决定,处理内部应聘者,注重培养一个人的学习敏锐度。
  • 根据一个人的领导力评估,可以将人分成九大不同类别的领导力人群,分别是:冲动者、机会主义者、外交家、专家、实干家、重构者、转型者、炼金术士和嘲讽者。 冲动者一般是指做事完全靠本能、没有章法,就像是刚出生的婴儿只会哭喊一样,只有这类领导力的人根本无法走上管理者岗位。而嘲讽者属于千年一遇的奇才,他已经具备改变世界和人类命运,他的思想可能会影响世世代代,比如老子,那种人极其稀少,也不会存在于企业里,所以这两类领导力都可以忽略。对团队和企业比较重要的领导力就是中间七种,即机会主义者、外交家、专家、实干家、重构者、转型者和炼金术士。
  • 外交家:遵守规则、避免内在和外在的冲突、适应环境、压抑自己的欲望、忠于群体、希望融入集体、是非分明、在意外表/身份、落入俗套、努力达到群体标准。从这些特质定义中可以看出来外交家更多是想让自己融入群体、排斥异类,尽可能让自己符合群体要求,但是也难免看上去圆滑没有创新。据培训教练说,很多企业里的VP(Vice President),虽然职位级别很高,都是只在外交家的层面。
  • 如果降低一个层次,把一个工作当作一份事业,这样就能在获得成就感的同时兼顾个人利益。把工作当作事业的人,我们经常称其有“事业心”。有事业心的人和没有事业心的人区别非常大,有事业心的人对自己做的事情有一种内在的动力,会有比较强的目标感,同时有长远的规划。

你拿到手的一万块钱,公司为此付出了多少钱?

绝大多数的人因为没有创办过公司,所以其实不太了解自己的工资的组成部分和企业付出的成本,甚至有很多人可能终其一生,都无法理解自己的工资薪金的组成部分。

最近刚好看到一个「中国薪资计算器」,借此机会,和大家聊一聊我们的工资的构成。

企业招聘一个员工是有成本的,你拿到手的现金 = 公司成本 – 公司承担的保险和公积金 – 个人承担的保险和公积金。所以,你到手的是一万块钱,但其实公司可能承担了不止一万块钱。

以天津为例,假设你一个月的税后收入是一万块钱,那么意味着你的税前收入是一万三千余元。差值的这三千余元,便是你自己缴纳的社保、公积金、个税的部分;而公司需要为你支付的整体成本,则是一万八千余元。差值的这五千余元,则是由公司承担的公积金和社保的部分。

一个详细的表单,可以参考下方的说明:

通过上面的表,你就明白了,为什么很多时候,企业主在招人上是十分肉疼的。企业主明明支付了 138% 的成本,但因为各种保险和公积金,真正到员工手里的只有 75% 了。

在一些劳动密集型行业当中,员工们往往喜欢不走社保,不打卡里,而是通过现金发放,也是希望规避掉公积金和各种保险。虽然可以减少保险和公积金的支出,但另一方面, 也致使劳动者失去了相应的保障。得不偿失。

如果你希望提升自己的税后收入,还是积极提升自己,让自己成为一个更贵的人吧。

two person sitting on camping chairs while watching mountain

保持简单、干净、平静的生活

总的来说,我还算是一个比较喜欢追求简单的生活的人。

虽然我依然会喜欢出门去吃饭(懒得自己做,或者是想吃的确实自己做不好,比如烤鱼),但不妨碍我其实在大多数时候只要能吃饱就行;

虽然我依然喜欢买买买,但不妨碍我大部分时候其实都不用我买的东西(这也是为啥近几年我开始疯狂断舍离),更多的时候,都是拿着之前买的东西,重复使用。

我们需要保持一个简单、干净、平静的生活,这样的生活方式让我们可以有充足的时间投入在我们想要做的事情当中,让我们可以专心专意,投身创作。

让自己的物质生活变得简单,让自己的精神生活变得丰富,才是我们应该追求的内容。

三个有用的 Golang 辅助网站

在我数十年的编程生涯里,我大部分时间写的都是动态类型语言,所以我对于类型并不太感冒。不过,当我在写 Golang 的时候,确实遇到了一些过去写 PHP、 Node.js、前端不同的问题。

一个最令我困扰的点便是:对于 JSON 的处理,需要先定义结构体来做转换。对于一些简单的 JSON 结构,我还可以简单的完成定义。但如果是一些比较复杂的结构体,我就放弃了手动定义,而是选择借助一些辅助工具来完成

比如我最常用的便是各种 JSON to Go 的网站,贴一个 JSON 进去,然后自动生成对应的 Golang 的 Struct,接下来我只需要复制右侧生成的 Struct 到我的代码里,就可以完成 JSON 的定义,使用 Golang 自带的 JSON 库解析即可。

截图的网站是 https://mholt.github.io/json-to-go/

另外一个可以实现 JSON 转换成 Go Struct 的网站是 https://transform.tools/json-to-go,它提供了更加全面的转换路径。不过有些时候选择太多也会让我有点困惑。

另外一个令我困扰的也是类似的格式转换,不过是 YAML 的。思路相同,手写要配置的 YAML 文件,并生成对应的 Struct: https://zhwt.github.io/yaml-to-go/。在设计风格上,和上面的 JSON2Struct 类似,是基于上面的项目改造过来的。

除此之外,如果你在定义 YAML 的时候, 对于部分数据如何定义不太明确,可以考虑使用 JSON2Yaml 的工具来实现将你需要的数据转换为 YAML 定义。

在 Go 当中嵌入父目录中的文件

自 Go 1.16 版本开始,Go 提供了将二进制文件打包进入到 Binary 文件当中的机制:`//go:embed。不过,我看到的示例大多数都是嵌入当前文件夹下的子文件夹的示例。并没有嵌入父一级文件夹的示例。于是,我便开始研究起来。

为什么会需要嵌入父目录中的文件?

这是因为不同的项目的构建规则不同。一些小型项目可能只有一个 main.go 或同级目录下几个其他的 go source 文件即可,但对于更大型的项目,合理的项目拆分是有助于帮助提升项目的可维护性的。

以我为例,我的目录结构如下:biz 目录下是我的核心逻辑,也是我日常写代码的地方;conf 则放置了各种配置,比如各种 API Key,ral 则是网络访问层,比如我比较喜欢用 gin 来做底层的网络访问层;script 放置了开发所需要的各种脚本文件;static 则放置了前端所需要的 JS / CSS 文件。在开发一些偏内容向的页面时,我会习惯使用 Server Side Render,所以我在 biz 目录下还有一个 template 目录。而主要的逻辑则放在 handler。

├── biz
│   ├── dal
│   ├── handler
│   ├── logic
│   ├── service
│   └── template
├── conf
├── ral
│   └── gin
├── script
└── static
    └── public

在日常开发时,一个非常常见的操作是在 handler 里处理基本的逻辑,并将 template 中的模板渲染出来,并返回给用户,这个时候就需要在 handler 里使用上一级目录的文件了。

错误的尝试1:使用 .. 来引入

作为文件系统的常规配置,我自然知道可以通过 .. 来代表上一级目录,因此我试着使用如下的语法来引入文件

//go:embed ../template/*

结果报了个错误 invalid pattern syntax。看得出来,是因为我的语法出现了问题。

通过搜索,我找到了这个 Github issue,才得知,由于避免跨模块的访问,go embed 阻止了 .. 语法的使用

Because embed.Files implements fs.FS, it cannot provide access to files with names beginning with .., so files in parent directories are also disallowed entirely, even when the parent directory named by .. does happen to be in the same module.

https://go.googlesource.com/proposal/+/master/design/draft-embed.md

错误的尝试2: 使用 go:generate 来执行复制

在上面的 issue 当中,我注意到还有另外一个方式,可以实现类似的效果。可以借助 go:generate来实现在执行 go generate 方法时,复制文件到本地,这样就可以实现在 Build 二进制文件之前,把文件复制到本地,即规避了跨模块的问题,也避免了将 template 文件放在本地,污染代码目录的问题。

//go:generate cp -r ../../assets ./local-asset-dir
//go:embed local-asset-dir
var assetFs embed.FS

这个方法在运行的时候没有效果,不过在其他人可能是有效果的(我猜是因为我开发时很少直接用 go generate,都是直接 go run 了)。不过,这个方法也有个问题,因为是写在代码本身当中的,很有可能后续因为某些原因,这些代码被误删除或修改了,导致整个系统的运行不正常。而散落在各文件的描述也会使得修复十分复杂。

正确的做法

在看这个 issue 的最后,我注意到了正确的用法,在另外一个 issue 当中,开发者 tomasf 提到了,我们应该在 asset 目录下创建一个 embed.go 来完成 embedFs 的建立,并在其他文件直接引入这个文件,完成定义。

You can create a embed.go file in your assets directory and make the assets available as it’s own package to the rest of your program.

tomasf

这个说法一出,豁然开朗!尝试一下,果然有效。我在 template 目录下创建了一个 embed.go 文件,并添加了如下代码。

package template

import "embed"

//go:embed *
var TemplateFs embed.FS

并在另外一个文件当中使用template.TemplateFs.ReadFile("index.tmpl") 来完成模板文件的引用。这样既不违背 golang 的跨模块,也不会使得代码不可维护,非常好。

参考阅读

  • https://go.googlesource.com/proposal/+/master/design/draft-embed.md
  • https://github.com/golang/go/issues/46056
  • https://github.com/golang/go/issues/41191#issuecomment-686621090
  • https://blog.carlmjohnson.net/post/2016-11-27-how-to-use-go-generate/
  • https://blog.carlmjohnson.net/post/2021/how-to-use-go-embed/