十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
———文章来源 YamiOdymel/PHP-to-Golang
“只有客户发展了,才有我们的生存与发展!”这是成都创新互联的服务宗旨!把网站当作互联网产品,产品思维更注重全局思维、需求分析和迭代思维,在网站建设中就是为了建设一个不仅审美在线,而且实用性极高的网站。创新互联对成都网站建设、成都网站制作、网站制作、网站开发、网页设计、网站优化、网络推广、探索永无止境。
PHP和模块之间的关系令人感到烦躁,假设你要读取 yaml 档案,你需要有一个 yaml 的模块,为此,你还需要将其编译然后将编译后的模块摆放至指定位置,之后换了一台伺服器你还要重新编译,这点到现在还是没有改善;顺带一提之后出了PHP 7效能确实提升了许多(比Python 3快了些),但PHP仍令我感到臃肿,我觉得是时候
(转行)了。
PHP 和Golang 的效能我想毋庸置疑是后者比较快(而且是以倍数来算),也许有的人会认为两种不应该被放在一起比较,但Golang 本身就是偏向Web 开发的,所以这也是为什么我考虑转用Golang 的原因,起初我的考虑有几个:Node.js 和Rust 还有最终被选定的Golang;先谈谈Node.js 吧。
Node.js的效能可以说是快上PHP 3.5倍至6倍左右 ,而且撰写的语言还是JavaScript,蒸蚌,如此一来就不需要学习新语言了!搭配Babel更可以说是万能,不过那跟「跳跳虎」一样的Async逻辑还有那恐怖的Callback Hell,有人认为前者是种优点,这点我不否认,但是对学习PHP的我来说太过于"Mind Fuck",至于后者的Callback Hell虽然有Promise,但是那又是另一个「Then Hell」的故事了。相较于Golang之下,Node.js似乎就没有那么吸引我了。你确实可以用Node.js写出很多东西,不过那V8引擎的效能仍然有限,而且要学习新的事物,不就应该是「全新」的吗;)?
题外话: 为什么Node.js不适合大型和商业专案?
在抛弃改用Node.js 之后我曾经花了一天的时间尝试Rust 和Iron 框架,嗯⋯⋯Rust 太强大了,强大到让我觉得Rust 不应该用在这里,这想法也许很蠢,但Rust 让我觉得适合更应该拿来用在系统或者是部分底层的地方,而不应该是网路服务。
Golang是我最终的选择,主要在于我花了一天的时间来研究的时候意外地发现Golang夭寿简洁( 关键字只有25个 ),相较之下Rust太过于「强大」令我怯步;而且Golang带有许多工具,例如 go fmt 会自动帮你整理程式码、 go doc 会自动帮你生产文件、 go test 可以自动单元测试并生产覆盖率报表、也有 go get 套件管理工具(虽然没有版本功能),不过都很实用,而且也不需要加上分号( ; ),真要说不好的地方⋯⋯大概就是强迫你花括号不能换行放吧(没错,我就是花括号会换行放的人)。
当我在撰写这份文件的时候 我会先假设你有一定的基础 ,你可以先阅读下列的手册,他们都很不错。
你能够在PHP 里面想建立一个变数的时候就直接建立,夭寿赞,是吗?
蒸蚌!那么Golang 呢?在Golang 中变数分为几类:「新定义」、「预先定义」、「自动新定义」、「覆盖」。让我们来看看范例:
在PHP中你会很常用到 echo 来显示文字,像这样。
然而在Golang中你会需要 fmt 套件,关于「什么是套件」的说明你可以在文章下述了解。
这很简单,而且两个语言的用法相差甚少,下面这是PHP:
只是Golang 稍微聒噪了一点,你必须在函式后面宣告他最后会回传什么资料型别。
在PHP 中你要回传多个资料你就会用上阵列,然后将资料放入阵列里面,像这样。
然而在Golang 中你可以不必用到一个阵列,函式可以一次回传多个值:
两个语言的撰写方式不尽相同。
主要是PHP 的阵列能做太多事情了,所以在PHP 里面要储存什么用阵列就好了。
在Golang里⋯⋯没有这么万能的东西,首先要先了解Golang中有这些型态: array , slice , map , interface ,
你他妈的我到底看了三洨,首先你要知道Golang是个强型别语言,意思是你的阵列中 只能有一种型态 ,什么意思?当你决定这个阵列是用来摆放字串资料的时候,你就只能在里面放字串。没有数值、没有布林值,就像你没有女朋友一样。
先撇开PHP 的「万能阵列」不管,Golang 中的阵列既单纯却又十分脑残,在定义一个阵列的时候,你必须给他一个长度还有其内容存放的资料型态,你的阵列内容不一定要填满其长度,但是你的阵列内容不能超过你当初定义的长度。
切片⋯⋯这听起来也许很奇怪,但是你确实可以「切」他,让我们先谈谈「切片」比起「阵列」要好在哪里:「你不用定义其最大长度,而且你可以直接赋予值」,没了。
我们刚才有提到你可以「切」他,记得吗?这有点像是PHP中的 array_slice() ,但是Golang直接让Slice「内建」了这个用法,其用法是: slice[开始:结束] 。
在PHP中倒是没有那么方便,在下列PHP范例中你需要不断地使用 array_slice() 。
你可以把「映照」看成是一个有键名和键值的阵列,但是记住:「你需要事先定义其键名、键值的资料型态」,这仍限制你没办法在映照中存放多种不同型态的资料。
在Golang里可就没这么简单了,你需要先用 make() 宣告 map 。
也许你不喜欢「接口」这个词,但用「介面」我怕会误导大众,所以,是的,接下来我会继续称其为「接口」。还记得你可以在PHP 的关联阵列里面存放任何型态的资料吗,像下面这样?
现在你有福了!正因为Golang中的 interface{} 可以接受任何内容,所以你可以把它拿来存放任何型态的资料。
有时候你也许会有个不定值的变数,在PHP 里你可以直接将一个变数定义成字串、数值、空值、就像你那变心的女友一样随时都在变。
在Golang中你必须给予变数一个指定的资料型别,不过还记得刚才提到的:「Golang中有个 interface{} 能够 存放任何事物 」吗( 虽然也不是真的任何事物啦⋯⋯ )?
当我们程式中不需要继续使用到某个资源或是发生错误的时候,我们索性会将其关闭或是抛弃来节省资源开销,例如PHP 里的读取档案:
在Golang中,你可以使用 defer 来在函式结束的时候自动执行某些程式(其执行方向为反向)。所以你就不需要在函式最后面结束最前面的资源。
defer 可以被称为「推迟执行」,实际上就是在函式结束后会「反序」执行的东西,例如你按照了这样的顺序定义 defer : A-B-C-D ,那么执行的顺序其实会是 D-C-B-A ,这用在程式结束时还蛮有用的,让我们看看Golang如何改善上述范例。
这东西很邪恶,不是吗?又不是在写BASIC,不过也许有时候你会在PHP 用上呢。但是拜托,不要。
Golang中仅有 for 一种回圈但却能够达成 foreach 、 while 、 for 多种用法。普通 for 回圈写法在两个语言中都十分相近。
在Golang请记得:如果你的 i 先前并不存在,那么你就需要定义它,所以下面这个范例你会看见 i := 0 。
在PHP里, foreach() 能够直接给你值和键名,用起来十分简单。
Golang里面虽然仅有 for() 但却可以使用 range 达成和PHP一样的 foreach 方式。
一个 while(条件) 回圈在PHP里面可以不断地执行区块中的程式,直到 条件 为 false 为止。
在Golang里也有相同的做法,但仍是透过 for 回圈,请注意这个 for 回圈并没有任何的分号( ; ),而且一个没有条件的 for 回圈会一直被执行。
PHP中有 do .. while() 回圈可以先做区块中的动作。
在Golang中则没有相关函式,但是你可以透过一个无止尽的 for 回圈加上条件式来让他结束回圈。
要是你真的希望完全符合像是PHP那样的设计方式,或者你可以在Golang中使用很邪恶的 goto 。
在PHP中我们可以透过 date() 像这样取得目前的日期。
在Golang就稍微有趣点了,因为Golang中并不是以 Y-m-d 这种格式做为定义,而是 1 、 2 、 3 ,这令你需要去翻阅文件,才能够知道 1 的定义是代表什么。
俗话说:「爆炸就是艺术」,可爱的PHP用词真的很大胆,像是: explode() (爆炸)、 die() (死掉),回归正传,如果你想在PHP里面将字串切割成阵列,你可以这么做。
简单的就让一个字串给「爆炸」了,那么Golang 呢?
对了,记得引用 strings 套件。
这真的是很常用到的功能,就像物件一样有着键名和键值,在PHP 里面你很简单的就能靠阵列(Array)办到。
真是太棒了,那么Golang呢?用 map 是差不多啦。如果有必要的话,你可以稍微复习一下先前提到的「多资料储存型态-Stores」。
你很常会在PHP里面用 isset() 检查一个索引是否存在,不是吗?
在Golang里面很简单的能够这样办到(仅适用于 map )。
指针(有时也做参照)是一个像是「变数别名」的方法,这种方法让你不用整天覆盖旧的变数,让我们假设 A = 1; B = A; 这个时候 B 会复制一份 A 且两者不相干,倘若你希望修改 B 的时候实际上也会修改到 A 的值,就会需要指针。
指针比起复制一个变数,他会建立一个指向到某个变数的记忆体位置,这也就是为什么你改变指针,实际上是在改变某个变数。
在Golang你需要用上 * 还有 符号。
有些时候你会回传一个阵列,这个阵列里面可能有资料还有错误代号,而你会用条件式判断错误代号是否非空值。
在Golang中函式可以一次回传多个值。为此,你不需要真的回传一个阵列,不过要注意的是你将会回传一个属于 error 资料型态的错误,所以你需要引用 errors 套件来帮助你做这件事。
该注意的是Golang没有 try .. catch ,因为 Golang推荐这种错误处理方式 ,你应该在每一次执行可能会发生错误的程式时就处理错误,而非后来用 try 到处包覆你的程式。
在 if 条件式里宣告变数会让你只能在 if 内部使用这个变数,而不会污染到全域范围。
也许你在PHP中更常用的会是 try .. catch ,在大型商业逻辑时经常看见如此地用法,实际上这种用法令人感到聒噪(因为你会需要一堆 try 区块):
Golang中并没有 try .. catch ,实际上Golang也 不鼓励这种行为 (Golang推荐逐一处理错误的方式),倘若你真想办倒像是捕捉异常这样的方式,你确实可以使用Golang中另类处理错误的方式(可以的话尽量避免使用这种方式): panic() , recover() , defer 。
你可以把 panic() 当作是 throw (丢出错误),而这跟PHP的 exit() 有87%像,一但你执行了 panic() 你的程式就会宣告而终,但是别担心,因为程式结束的时候会呼叫 defer ,所以我们接下来要在 defer 停止 panic() 。
关于 defer 上述已经有提到了,他是一个反向执行的宣告,会在函式结束后被执行,当你呼叫了 panic() 结束程式的时候,也就会开始执行 defer ,所以我们要在 defer 内使用 recover() 让程式不再继续进行结束动作,这就像是捕捉异常。
recover() 可以看作 catch (捕捉),我们要在 defer 里面用 recover() 解决 panic() ,如此一来程式就会回归正常而不会被结束。
还记得在PHP里要引用一堆档案的日子吗?到处可见的 require() 或是 include() ?到了Golang这些都不见了,取而代之的是「套件(Package)」。现在让我们来用PHP解释一下。
这看起来很正常对吧?但假设你有一堆档案,这马上就成了 Include Hell ,让我们看看Golang怎么透过「套件」解决这个问题。
「 蛤???杀小??? 」你可能如此地说道。是的, main.go 中除了引用 fmt 套件( 为了要输出结果用的套件 )之外完全没有引用到 a.go 。
「 蛤???杀小?????? 」你仿佛回到了几秒钟前的自己。
既然没有引用其他档案,为什么 main.go 可以输出 foo 呢?注意到了吗, 两者都是属于 main 套件 ,因此 他们共享同一个区域 ,所以接下来要介绍的是什么叫做「套件」。
套件是每一个 .go 档案都必须声明在Golang原始码中最开端的东西,像下面这样:
这意味着目前的档案是属于 main 套件( 你也可以依照你的喜好命名 ),那么要如何让同个套件之间的函式沟通呢?
接着是Golang;注意!你不需要引用任何档案,因为下列两个档案同属一个套件。
一个由「套件」所掌握的世界,比起PHP的 include() 和 require() 还要好太多了,对吗?
在Golang 中没有引用单独档案的方式,你必须汇入一整个套件,而且你要记住:「一定你汇入了,你就一定要使用它」,像下面这样。
假如你不希望使用你汇入的套件,你只是为了要触发那个套件的 main() 函式而引用的话⋯⋯,那么你可以在前面加上一个底线( _ )。
如果你的套件出现了名称冲突,你可以在套件来源前面给他一个新的名称。
现在你知道可以汇入套件了,那么什么是「汇出」?同个套件内的函式还有共享变数确实可以直接用,但那 并不表示可以给其他套件使用 ,其方法取决于 函式/变数的「开头大小写」 。
是的。 Golang依照一个函式/变数的开头大小写决定这个东西是否可供「汇出」 。
这用在区别函式的时候格外有用,因为小写开头的任何事物都是不供汇出的,反之,大写开头的任何事物都是用来汇出供其他套件使用的。
一开始可能会觉得这是什么奇异的规定,但写久之后,你就能发现比起JavaScript和Python以「底线为开头的命名方式」还要来得更好;比起成天宣告 public 、 private 、 protected 还要来得更快。
在Golang 中没有类别,但有所谓的「建构体(Struct)」和「接口(Interface)」,这就能够满足几乎所有的需求了,这也是为什么我认为Golang 很简洁却又很强大的原因。
让我们先用PHP 建立一个类别,然后看看Golang 怎么解决这个问题。
虽然Golang没有类别,但是「建构体(Struct)」就十分地堪用了,首先你要知道在Golang中「类别」的成员还有方法都是在「类别」外面所定义的,这跟PHP在类别内定义的方式有所不同,在Golang中还有一点,那就是他们没有 public 、 private 、 protected 的种类。
在PHP中,当有一个类别被 new 的时候会自动执行该类别内的建构子( __construct() ),通常你会用这个来初始化一些类别内部的值。
但是在Golang 里因为没有类别,也就没有建构子,不巧的是建构体本身也不带有建构子的特性,这个时候你只能自己在外部建立一个建构用函式。
让我们假设你有两个类别,你会把其中一个类别传入到另一个类别里面使用,废话不多说!先上个PHP 范例(为了简短篇幅我省去了换行)。
在Golang中你也有相同的用法,但是请记得:「 任何东西都是在「类别」外完成建构的 」。
在PHP 中没有相关的范例,这部分会以刚才「嵌入」章节中的Golang 范例作为解说对象。
你可以看见Golang在进行 Foo 嵌入 Bar 的时候,会自动将 Foo 的成员暴露在 Bar 底下,那么假设「双方之间有相同的成员名称」呢?
这个时候被嵌入的成员就会被「遮蔽」,下面是个实际范例,还有你如何解决遮蔽问题:
虽然都是呼叫同一个函式,但是这个函式可以针对不同的资料来源做出不同的举动,这就是多形。你也能够把这看作是:「讯息的意义由接收者定义,而不是传送者」。
目前PHP 中没有真正的「多形」,不过你仍可以做出同样的东西。
嗯⋯⋯那么Golang呢?实际上更简单而且更有条理了,在Golang中有 interface 可以帮忙完成这个工作。
如果你对Interface还不熟悉,可以试着查看「 解释Golang中的Interface到底是什么 」文章。
谢谢你看到这里,可惜这篇文章却没有说出Golang 最重要的卖点:「Goroutine」和「Channel」
我保证的英文翻译是I Promise 。\x0d\x0a词汇分析\x0d\x0a释义:我承诺; 我答应你\x0d\x0a拓展资料\x0d\x0a1,I promise you to leave. \x0d\x0a我答应你(我)走。 \x0d\x0a2,No, I promise you. \x0d\x0a不,我答应你。 \x0d\x0a3,If you have patience with me I promise I will not give up. \x0d\x0a如果你有点耐心与我,我保证我将不放弃。 \x0d\x0a4,I'll wait for you, I promise you, I will. \x0d\x0a我会等着你的,我向你保证! \x0d\x0a5,I promise I'll be loyal to you forever. \x0d\x0a我承诺我将对你永远忠诚。
TypeScript非常优秀。它完美地结合了强类型和快速开发,因此非常好用,我在许多情况下都会默认选择这个库。但是,世上没有完美的语言,有些情况下TypeScript并不是最合适的工具:
对于这些情况,TypeScript开发人员最好还是选用其他语言。C#、Go和Java都是非常好的选择。它们的速度远超 TypeScript,每种语言都有自己的长处。C#能与TypeScript配合得很好,我来解释一下为什么。
C#能与TypeScript配合得很好,因为它们看上去就像是同一种语言。两者都是由Anders Hejlsberg设计的,而且从许多方面来看, TypeScript就是添加了C#的JavaScript 。它们的特性和语法都很相似,因此在同一个项目中结合使用二者非常容易。更重要的是,C#的语言与TypeScript很相似,因此开发人员阅读和编写代码也非常轻松。
相反,Go是一种完全不同的语言:没有类,没有继承,没有异常,没有包级别的封装(只有类级别的封装),而且语法也完全不同。当然这并不一定是坏事,但开发人员的确需要重新思考并用不同的方式设计代码,因此,同时使用Go和TypeScript是比较困难的。不过,Java与C#很相似,但依然缺乏许多C#和TypeScript都有的功能。
也许你已经知道,C#和TypeScript有很多相似之处,如基于C的语法、类、接口、泛型等。下面,我来详细列举一下二者的相似之处:
async/await
首先,C#和JavaScript都使用async/await来处理异步代码。在JavaScript中,异步操作用Promise表示,而应用程序可以await一个异步操作结束。C#中的Promise其实是Task,概念上与Promise完全相同,也有相应的方法。下面的例子演示了两种语言中async/await的用法:
C#和JavaScript都用熟悉的=语法(即箭头函数)来表示lambda表达式。下面是TypeScript和C#的比较:
TypeScript中使用lambda表达式
C#中使用lambda表达式
上述示例演示了C#的System.Linq命名空间中的一些方法,相当于JavaScript的函数式数组方法。下面是JavaScript的数组方法与等价的C# Linq方法:
如前所述,世上没有完美的语言。在设计语言时总要有所权衡,所以一些语言的速度更快,但使用难度会增加(例如Rust的借出检查)。另一方面,一些语言非常易用,但通常性能的优化难度就会增加(例如JavaScript的动态语言特性)。正因如此,我相信掌握一组相似的语言会非常有用:这些语言分别有各自的长处,但都很相似,而且能互相配合。例如,下面是我选择的一组语言:
TypeScript
C#
C++
这个我知道,歌词还蛮感人的。 Promise-郑龙华李弘基
I will promise you
tu nu nein nao man dam go sa la kar gei
双眼只看着你而活
I will promise you
tu pa len nao lan go sa la kar gei
双手抱着你而活
a chi mei nun dao cham den sun gan ga ji
nao ha na man keu lil gei
清晨睁眼直到入眠 只想你一人
sa lang hai yi ma li ji ma
我爱你 别忘了这句话
I love you forever
tao wun yao leum na lein
keu neu li duei jur gei
炎热的夏天 为你变成树荫
pi o nen na lei nen wu sa ni duei jur gei
下雨的日子 为你变成雨伞
kao da ga ji qir dai ein cha ken
ei ja do duel jur gei
走累的时候 为你变成小椅子
wu seuf dain ki bum tu bai ga duei kei
ham gei wu seur gei
笑的时候 比你开心两倍 和你一起笑
nun mur heur lin dain su gao ni duei
naor da ga jur gei
流泪的时候 变成手绢 为你擦泪
I will promise you
tu nu nein nao man dam go sa la kar gei
双眼只看着你而活
I will promise you
tu pa len nao lan go sa la kar gei
双手抱着你而活
a chi mei nun dao cham den sun gan ga ji
nao ha na man keu lil gei
清晨睁眼直到入眠 只想你一人
sa lang hai yi ma li ji ma
我爱你 别忘了这句话
I love you forever
I love you forever
wu li sa yi nen ma qi coffeedought ga ji
我们的关系就像咖啡和甜甜圈一样
nai gei ki bu meur jao nai jun
nao nen na ye special chip
给我带来快乐的你 是我的special chip
ha lu ha lu ga energy
bu jo ka da miaon emergency
一天天如果缺少energy的话 emergency
nai gei saing miang eur bu lao jur dai ko
man keu dai ye hiang gi
给我吹来生命的你甜蜜的香气
ha na ha na go sum
giao no wen na ye sa lang eur
每天一定要把隐藏起来的我的爱情
ham gei ha nen nar dong an mo du
bo yao jur gao ya
在相处的日子里一个一个全部都展现给你
I will promise you
ao di ei yi daon nao man ki yao kar gei
不管在哪里将只记住你
I will promise you
mo lai do nao ma neur ki yao kar gei
不管做什么都将只记住你
yaong wo ni nao leur sai gi li ka seu man
pua go sa la kar gao ya
抱着只将你永远刻在心中的想法活下去
sa lang hai yi mar ki yao kai
我爱你 记住这句话
I love you forever
Yes A.N.JELL right here
I will promise you just do it girl
sa lang han da nen dei mu
sen ma li pi lio hai
爱你还需要什么语言
kuang kuang kao li nen wen ju ga
seu meu go tai da par gei
用哐哐跳的左心回答你
one step two step three and four
ni giao tei chaon chao ni ta ga gar gei
慢慢走向你的身边
yi biao li lan mar da wo ni pei dam ji mo tai
离别的话徘徊在嘴边
I will take your love my dear
I will promise you
tu nu nein nao man dam go sa la kar gei
双眼只看着你而活
I will promise you
tu pa len nao lan go sa la kar gei
双手抱着你而活
a chi mei nun dao cham den sun gan ga ji
nao ha na man keu lil gei
清晨睁眼直到入眠 只想你一人
sa lang hai yi ma li ji ma
我爱你 别忘了这句话
I love you forever