﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-战魂小筑-随笔分类-Golang</title><link>http://www.cppblog.com/sunicdavy/category/21050.html</link><description>讨论群:309800774 知乎关注:http://zhihu.com/people/sunicdavy 开源项目:https://github.com/davyxu</description><language>zh-cn</language><lastBuildDate>Mon, 27 Dec 2021 16:46:30 GMT</lastBuildDate><pubDate>Mon, 27 Dec 2021 16:46:30 GMT</pubDate><ttl>60</ttl><item><title>但是GPU的性能依然还是DrawCall优化那一套</title><link>http://www.cppblog.com/sunicdavy/archive/2021/12/27/217892.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 27 Dec 2021 11:01:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2021/12/27/217892.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/217892.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2021/12/27/217892.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/217892.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/217892.html</trackback:ping><description><![CDATA[ Entitas的ECS系统

1. 本来在一个对象中添加一个类字段的过程，ECS需要添加一个类代表Component，并且代码生成。

这个字段一般用于描述对象的资源，处理显示的GameObject， 表示对象的类型等。



2. 本来一个对象的业务逻辑处理过程直接用方法解决的， ECS需要新加一个System，而操作对象需要使用Filter或Group查询获得。



3. 一系列的操作， 需要拆分为多个System和Component拆分处理。如果System顺序不对， 会造成一些诡异的bug。



4. Component不仅仅是Model承载体， 也可以是参数的数据结构。参数Component通过Entity传递到System处理。 例如： 通过ECS创建一个方块的过程，使用CreateTileComponent，包含创建Tile的位置， 创建Entity并添加CreateTileComponent， 在CreateTileSystem中处理就创建了Tile，处理完成时， 需要将传入的Entity.Destroy掉。



6. Entity上修改Component的过程， 会触发事件。修改的过程需要使用RelaceXXX，XXX表示组件名。组件可以频繁修改， 不用担心添加和删除组件过程的性能， Entitas底层处理性能只相当于指针赋值的性能。



ECS像什么？

1. ECS中的System类似触发器系统（Event-Condition-Action），其中，Event对应Entitas的GetTrigger+Collector，表示触发事件。Condition对应Filter表示在事件来源对象中找到需要的对象。 Action对应Execute，表示实际的操作。

2. ECS中的Component类似不用lua扩展的Redis或者不用存储过程的MySQL， 纯粹纯数据， 而不能对数据有任何封装操作。没有lua和存储过程支持的db写起来还是比较费劲的，但ECS就是那么的纯。



3. ECS中的Entity很尴尬，因为Component是按类别连续存储的以保证性能。 逻辑又需要Entity组合成逻辑需要的复合对象。 两边都要照顾，所以这种设计就让代码量巨增，可读性下降。





ECS企图用一套框架灭掉设计模式

1. 单件（Singleton）在Entitas用Unique标签标记Component， 在Context中就是唯一的， 其实也就是Singleton。



2. ECS干掉了传统的工厂模式，底层统一对对象（Entity）和属性（Component）统一管理。需要按Component中的值找回Entity时， 可以使用EntityIndex。



3. Entity携带不同的组件时，整个创建和销毁过程被记录并恢复，其实就是Command模式



ECS适合做UI框架（类似MVVM，MVC,MVP）么？

ECS不是专用的UI框架，但是可以对不同系统和数据间解耦。传统代码中数据修改后的Callback，ECS也可以用Listener做， 但Listener因为能保存数据， 就需要用Component保存。 所以你需要面对的是，一个Button，响应创建一个参数用的Component和System，还要为数据改变写一套ListenComponent和Listener处理的System，酸爽吧？



Minecraft适合ECS来做么？

可以，性能应该能提升不少，但是代码会更繁琐，特别像Java这种啰嗦语言配上ECS这种啰嗦框架，估计代码量翻翻还是很轻松的。MC属于特殊类型的游戏，适合特殊领域特别优化，也就是专门为方块做出特别的设计来做优化。ECS属于通用框架，即便性能OK，但是代码未必能有良好的可读性。



体量小的游戏适合用ECS来做么？

可以，但不建议。特别是只有几个人维护的工程，贸然上ECS系统，会让系统变的极为复杂。当然你会说，如果开发到后期，传统开发模式会导致代码会乱，ECS会好些吧。掌握ECS也不是一天两天的事情，不熟悉ECS的程序员设计出来的系统获得的优势可能还不如用传统设计方法好呢。

架构解决的是人的问题， 人都有问题，用什么框架都没办法。



到底什么项目适合用ECS？

1. 大量的小个体不断的生成和销毁以及显示，例如： 攻城战中，要体现每个角色的移动，战斗。

2. 多于5个人编写核心战斗逻辑。互相协作和模块切分，需要一个大家都能信服的框架，ECS可以选择。



P.S.

不要造ECS的轮子！

很多同学看了ECS基本原理，在没有深入使用过任何ECS系统时马上操刀造轮子。ECS系统确实看起来简单。实际造下来你会发现，性能非常糟糕以及不知道一些逻辑如何用ECS来解决。



总结：

1. ECS确实为性能而生，没有并发加持性能的ECS都是耍流氓，要快就要快到极致。

2. Unity中，ECS并发能扩展CPU的利用率，但是GPU的性能依然还是DrawCall优化那一套，别期望ECS会颠覆Unity，性能也不会快到飞起，关键还是要看具体的项目和人。

3. ECS是万能框架，但不全能。传统架构和设计思想也不是一无是处，熟啥用啥，怎么快怎么来！


https://mip.bmlink.com/wu19870821/news/2611408.html
https://mip.bmlink.com/wu19870821/news/2611409.html
https://mip.bmlink.com/wu19870821/news/2611410.html
https://mip.bmlink.com/wu19870821/news/2611411.html
https://mip.bmlink.com/wu19870821/news/2611412.html
https://mip.bmlink.com/wu19870821/news/2611413.html
https://mip.bmlink.com/wu19870821/news/2611414.html
https://mip.bmlink.com/wu19870821/news/2611415.html
https://mip.bmlink.com/wu19870821/news/2611416.html
https://mip.bmlink.com/wu19870821/news/2611417.html
https://m.bmlink.com/wu19870821/news/2611408.html
https://m.bmlink.com/wu19870821/news/2611409.html
https://m.bmlink.com/wu19870821/news/2611410.html
https://m.bmlink.com/wu19870821/news/2611411.html
https://m.bmlink.com/wu19870821/news/2611412.html
https://m.bmlink.com/wu19870821/news/2611413.html
https://m.bmlink.com/wu19870821/news/2611414.html
https://m.bmlink.com/wu19870821/news/2611415.html
https://m.bmlink.com/wu19870821/news/2611416.html
https://m.bmlink.com/wu19870821/news/2611417.html
https://wu19870821.bmlink.com/news/2611408.html
https://wu19870821.bmlink.com/news/2611409.html
https://wu19870821.bmlink.com/news/2611410.html
https://wu19870821.bmlink.com/news/2611411.html
https://wu19870821.bmlink.com/news/2611412.html
https://wu19870821.bmlink.com/news/2611413.html
https://wu19870821.bmlink.com/news/2611414.html
https://wu19870821.bmlink.com/news/2611415.html
https://wu19870821.bmlink.com/news/2611416.html
https://wu19870821.bmlink.com/news/2611417.html
https://www.bmlink.com/wu19870821/news/2611408.html
https://www.bmlink.com/wu19870821/news/2611409.html
https://www.bmlink.com/wu19870821/news/2611410.html
https://www.bmlink.com/wu19870821/news/2611411.html
https://www.bmlink.com/wu19870821/news/2611412.html
https://www.bmlink.com/wu19870821/news/2611413.html
https://www.bmlink.com/wu19870821/news/2611414.html
https://www.bmlink.com/wu19870821/news/2611415.html
https://www.bmlink.com/wu19870821/news/2611416.html
https://www.bmlink.com/wu19870821/news/2611417.html
https://mip.bmlink.com/chaoweifensuiji/news/2611407.html
https://mip.bmlink.com/chaoweifensuiji/news/2611406.html
https://mip.bmlink.com/chaoweifensuiji/news/2558756.html
https://mip.bmlink.com/chaoweifensuiji/news/2558753.html
https://mip.bmlink.com/chaoweifensuiji/news/2558748.html
https://mip.bmlink.com/chaoweifensuiji/news/2558743.html
https://mip.bmlink.com/chaoweifensuiji/news/2558740.html
https://mip.bmlink.com/chaoweifensuiji/news/2558737.html
https://mip.bmlink.com/chaoweifensuiji/news/2558731.html
https://m.bmlink.com/chaoweifensuiji/news/2611407.html
https://m.bmlink.com/chaoweifensuiji/news/2611406.html
https://m.bmlink.com/chaoweifensuiji/news/2558756.html
https://m.bmlink.com/chaoweifensuiji/news/2558753.html
https://m.bmlink.com/chaoweifensuiji/news/2558748.html
https://m.bmlink.com/chaoweifensuiji/news/2558743.html
https://m.bmlink.com/chaoweifensuiji/news/2558740.html
https://m.bmlink.com/chaoweifensuiji/news/2558737.html
https://m.bmlink.com/chaoweifensuiji/news/2558731.html
https://chaoweifensuiji.bmlink.com/news/2611407.html
https://chaoweifensuiji.bmlink.com/news/2611406.html
https://chaoweifensuiji.bmlink.com/news/2558756.html
https://chaoweifensuiji.bmlink.com/news/2558753.html
https://chaoweifensuiji.bmlink.com/news/2558748.html
https://chaoweifensuiji.bmlink.com/news/2558743.html
https://chaoweifensuiji.bmlink.com/news/2558740.html
https://chaoweifensuiji.bmlink.com/news/2558737.html
https://chaoweifensuiji.bmlink.com/news/2558731.html
https://www.bmlink.com/chaoweifensuiji/news/2611407.html
https://www.bmlink.com/chaoweifensuiji/news/2611406.html
https://www.bmlink.com/chaoweifensuiji/news/2558756.html
https://www.bmlink.com/chaoweifensuiji/news/2558753.html
https://www.bmlink.com/chaoweifensuiji/news/2558748.html
https://www.bmlink.com/chaoweifensuiji/news/2558743.html
https://www.bmlink.com/chaoweifensuiji/news/2558740.html
https://www.bmlink.com/chaoweifensuiji/news/2558737.html
https://www.bmlink.com/chaoweifensuiji/news/2558731.html
https://mip.bmlink.com/towercrane/news/2541940.html
https://mip.bmlink.com/towercrane/news/2541945.html
https://mip.bmlink.com/towercrane/news/2541950.html
https://mip.bmlink.com/towercrane/news/2541966.html
https://mip.bmlink.com/towercrane/news/2541991.html
https://mip.bmlink.com/towercrane/news/2541992.html
https://mip.bmlink.com/towercrane/news/2541993.html
https://mip.bmlink.com/towercrane/news/2541994.html
https://mip.bmlink.com/towercrane/news/2541995.html
https://m.bmlink.com/towercrane/news/2541940.html
https://m.bmlink.com/towercrane/news/2541945.html
https://m.bmlink.com/towercrane/news/2541950.html
https://m.bmlink.com/towercrane/news/2541966.html
https://m.bmlink.com/towercrane/news/2541991.html
https://m.bmlink.com/towercrane/news/2541992.html
https://m.bmlink.com/towercrane/news/2541993.html
https://m.bmlink.com/towercrane/news/2541994.html
https://m.bmlink.com/towercrane/news/2541995.html
https://towercrane.bmlink.com/news/2541940.html
https://towercrane.bmlink.com/news/2541945.html
https://towercrane.bmlink.com/news/2541950.html
https://towercrane.bmlink.com/news/2541966.html
https://towercrane.bmlink.com/news/2541991.html
https://towercrane.bmlink.com/news/2541992.html
https://towercrane.bmlink.com/news/2541993.html
https://towercrane.bmlink.com/news/2541994.html
https://towercrane.bmlink.com/news/2541995.html
https://www.bmlink.com/towercrane/news/2541940.html
https://www.bmlink.com/towercrane/news/2541945.html
https://www.bmlink.com/towercrane/news/2541950.html
https://www.bmlink.com/towercrane/news/2541966.html
https://www.bmlink.com/towercrane/news/2541991.html
https://www.bmlink.com/towercrane/news/2541992.html
https://www.bmlink.com/towercrane/news/2541993.html
https://www.bmlink.com/towercrane/news/2541994.html
https://www.bmlink.com/towercrane/news/2541995.html
https://mip.bmlink.com/xxmjhw888/news/2611429.html
https://mip.bmlink.com/xxmjhw888/news/2611428.html
https://mip.bmlink.com/xxmjhw888/news/2611427.html
https://mip.bmlink.com/xxmjhw888/news/2611426.html
https://mip.bmlink.com/xxmjhw888/news/2611425.html
https://mip.bmlink.com/xxmjhw888/news/2611424.html
https://mip.bmlink.com/xxmjhw888/news/2611423.html
https://mip.bmlink.com/xxmjhw888/news/2611422.html
https://mip.bmlink.com/xxmjhw888/news/2611421.html
https://mip.bmlink.com/xxmjhw888/news/2611420.html
https://mip.bmlink.com/xxmjhw888/news/2611419.html
https://mip.bmlink.com/xxmjhw888/news/2611418.html
https://m.bmlink.com/xxmjhw888/news/2611429.html
https://m.bmlink.com/xxmjhw888/news/2611428.html
https://m.bmlink.com/xxmjhw888/news/2611427.html
https://m.bmlink.com/xxmjhw888/news/2611426.html
https://m.bmlink.com/xxmjhw888/news/2611425.html
https://m.bmlink.com/xxmjhw888/news/2611424.html
https://m.bmlink.com/xxmjhw888/news/2611423.html
https://m.bmlink.com/xxmjhw888/news/2611422.html
https://m.bmlink.com/xxmjhw888/news/2611421.html
https://m.bmlink.com/xxmjhw888/news/2611420.html
https://m.bmlink.com/xxmjhw888/news/2611419.html
https://m.bmlink.com/xxmjhw888/news/2611418.html
https://xxmjhw888.bmlink.com/news/2611429.html
https://xxmjhw888.bmlink.com/news/2611428.html
https://xxmjhw888.bmlink.com/news/2611427.html
https://xxmjhw888.bmlink.com/news/2611426.html
https://xxmjhw888.bmlink.com/news/2611425.html
https://xxmjhw888.bmlink.com/news/2611424.html
https://xxmjhw888.bmlink.com/news/2611423.html
https://xxmjhw888.bmlink.com/news/2611422.html
https://xxmjhw888.bmlink.com/news/2611421.html
https://xxmjhw888.bmlink.com/news/2611420.html
https://xxmjhw888.bmlink.com/news/2611419.html
https://xxmjhw888.bmlink.com/news/2611418.html
https://www.bmlink.com/xxmjhw888/news/2611429.html
https://www.bmlink.com/xxmjhw888/news/2611428.html
https://www.bmlink.com/xxmjhw888/news/2611427.html
https://www.bmlink.com/xxmjhw888/news/2611426.html
https://www.bmlink.com/xxmjhw888/news/2611425.html
https://www.bmlink.com/xxmjhw888/news/2611424.html
https://www.bmlink.com/xxmjhw888/news/2611423.html
https://www.bmlink.com/xxmjhw888/news/2611422.html
https://www.bmlink.com/xxmjhw888/news/2611421.html
https://www.bmlink.com/xxmjhw888/news/2611420.html
https://www.bmlink.com/xxmjhw888/news/2611419.html
https://www.bmlink.com/xxmjhw888/news/2611418.html
https://www.ixueyi.com/qinggan/a_Tl9sM38K.html
https://www.ixueyi.com/falv/a_2I2ewPSh.html
https://www.ixueyi.com/falv/a_Y1Un4tSK.html
https://www.ixueyi.com/falv/a_9Q3N5R3R.html
https://www.ixueyi.com/falv/a_A9E8Pvl3.html
https://www.ixueyi.com/falv/a_2jy4G07C.html
https://www.ixueyi.com/falv/a_W5r2as2P.html
https://www.ixueyi.com/falv/a_a20P8p3T.html
https://www.ixueyi.com/falv/a_5jl15mkU.html
https://www.ixueyi.com/falv/a_C646nFN4.html
https://www.ixueyi.com/falv/a_n71xa7a2.html
https://www.ixueyi.com/falv/a_VCxaehV6.html
https://www.ixueyi.com/falv/a_7JhXF2L0.html
https://www.ixueyi.com/falv/a_y5tA5IdR.html
https://www.ixueyi.com/falv/a_qn722hR8.html
https://www.ixueyi.com/falv/a_yX5W85yK.html
https://www.ixueyi.com/renshi/a_r569sY1C.html
https://www.ixueyi.com/renshi/a_472EFKfF.html
https://www.ixueyi.com/renshi/a_umemPeiO.html
https://www.ixueyi.com/renshi/a_9o6T89n3.html
https://www.ixueyi.com/renshi/a_GX26np9Q.html
https://www.ixueyi.com/falv/a_4CAdyV14.html
https://www.ixueyi.com/falv/a_i28019yM.html
https://www.ixueyi.com/falv/a_b2fyO1od.html
https://www.ixueyi.com/falv/a_oq1MYAeY.html
https://www.ixueyi.com/falv/a_XSVSuYNm.html
https://www.ixueyi.com/falv/a_LUxNT8oA.html
https://www.ixueyi.com/falv/a_agNvlmr3.html<img src ="http://www.cppblog.com/sunicdavy/aggbug/217892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2021-12-27 19:01 <a href="http://www.cppblog.com/sunicdavy/archive/2021/12/27/217892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏与Web的服务器对比</title><link>http://www.cppblog.com/sunicdavy/archive/2018/08/29/215887.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 29 Aug 2018 03:16:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2018/08/29/215887.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/215887.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2018/08/29/215887.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/215887.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/215887.html</trackback:ping><description><![CDATA[<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">为了编写基于</span><a href="https://github.com/davyxu/cellnet"><span style="font-size: 16px; color: #003884;">cellnet</span></a><span style="font-size: 16px; color: #333333;">的新一代游戏服务器框架，最近深入研究微服务，ServiceMesh等概念。研究过程中对Web和游戏两种服务器架构设计有一些心得，编写并记录下来。(下文中，Game表示游戏服务器，Web表示Web服务器) `` </span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333; font-weight: bold;">状态缓存</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">所谓状态缓存，就是在内存而非专业数据缓存服务器（如redis）中保存和处理逻辑数据，手动编写此过程较为繁琐但是效率较高，但随着状态逻辑复杂性和并发、扩容问题提出，状态同步会变得越来越复杂。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Game:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">强交互性的服务器类型需要在服务器做缓存，逻辑编写也较为容易，无需处理事务并发问题。例如：组队，匹配，战斗逻辑。服务器不能随意重启。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">弱交互性的服务器类型可配合redis做成无状态服务器，例如：养成，技能升级，领取物品等。服务器随时支持重启。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">游戏服务器为了提高性能，早期所有服务器都是使用状态缓存写法编写，特别是MMORPG这类强交互的游戏服务器尤为严重。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Web:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">均为无状态服务器，弱交互。使用事务方式处理并发逻辑，例如：交易，下单等。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;"> </span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333; font-weight: bold;">推送，单独发送</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">这里提到的所谓推送，单独发送是与RPC区别的通讯方法。RPC要求请求必须有回应。而推送单独发送则更像是通知和广播，无需目的方返回任何消息。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Game:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">找到服务器的Session，直接Send</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">通过中转服务器，或称为中心服务器进行注册/广播</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">客户端的model数据需要更新时，服务器会主动推送消息。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">游戏服务器没有严格的RPC设计需求，推送和单独发送较Web服务器更多。而且游戏服务器多使用长连接，所以主动推送也比Web服务器来的方便一些。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Web:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">将推送做成专有的服务，并做排队和并发处理。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;"> </span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333; font-weight: bold;">可用性</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">听说过游戏停服更新，支付宝服务器在刷二维码时停服了可一定被骂惨吧。Web对服务器高可用性要求很高，游戏虽然也注重服务器稳定性和可用性，但是由于版本迭代更新频繁，停服更新反而能获得玩家接受。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Game:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">游戏对可用性要求不高。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">游戏大版本更新时需要停服更新。支持热更新技术的服务器（例如Erlang，Skynet）仅使用热更新修复bug，很少直接更新新版本。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">不是所有的游戏服务器支持动态添加服务器。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Web:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">极高的可用性，服务不允许停服更新，使用蓝绿及灰度方式更新服务器。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">随时可以横向扩展服务器，提高服务器容量和承载。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;"> </span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333; font-weight: bold;">连接及传输</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">均使用TCP传输协议，游戏服务器注重性能，自有协议及二进制协议使用较多。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Web注重兼容和接口友好，使用JSON格式较多。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Game:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">使用长连接，需要从逻辑层维护连接状态及处理服务器不在线情况</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">使用自有封包格式，大部分使用protobuf或二进制流格式。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Web:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">微服务大部分使用短连接，grpc支持http2长连接</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">使用json编码方便调试和版本兼容。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;"> </span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333; font-weight: bold;">流量限制</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">人数多了，任何服务器都扛不住，流量限制和登入限制能有效保护服务器稳定。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Game:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">单服有人数限制，可以通过GM后台设置挡墙，超过无法进入</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Web:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">限流器中间件，可以精确到服务控制流量</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;"> </span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333; font-weight: bold;">断流，防止雪崩</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Game:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">游戏没有，也不需要这种概念，游戏请求不会突然升高，即便有，也通过GM后台人为控制</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Web:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">断流器中间件 </span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333; font-weight: bold;">服务发现</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">如何找到服务器地址。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">服务有变化时，通过Watch系统通知订阅者更新本地缓存</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">服务器没有变化时，使用本地缓存找到服务地址</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Game:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">游戏服务器互相依赖复用只在很小的范围内，因此无需在不同语言不同进程服务间获得地址，大部分在配置文件中填写各服务的IP及地址即可互相访问。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">早期游戏自己编写服务器状态及地址发现服务。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">有用redis做服务发现</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Web:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">使用服务发现系统，分布式部署。无需依赖配置文件</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;"> </span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333; font-weight: bold;">网关需求</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Game:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">网关处理客户端上下线通知，心跳，维持连接，转发，广播上下行封包</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">Web:</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">根据请求地址路由，无上下线概念，无心跳。广播通过消息推送系统完成</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;"> </span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">由于笔者从事游戏行业，对Web服务器概念在逐渐熟悉中，若有错误和不足请各位大佬指出。</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 16px; color: #333333;">本人新书《Go语言从入门到进阶实战》，生动的语言，例子带有各种彩蛋，轻松了解Go语言特性，更有</span><a href="https://github.com/davyxu/cellnet"><span style="font-size: 16px; color: #003884;">cellnet</span></a><span style="font-size: 16px; color: #333333;">框架剖析解密</span></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div>
<div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"><a href="https://search.jd.com/Search?keyword=go%E8%AF%AD%E8%A8%80%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E8%BF%9B%E9%98%B6%E5%AE%9E%E6%88%98&amp;enc=utf-8&amp;suggest=1.def.0.V02&amp;wq=Go%E8%AF%AD%E8%A8%80%E4%BB%8E&amp;pvid=145d55a92cab4b07b71326f8beb1700b"><span style="font-size: 16px; color: #003884;">https://search.jd.com/Search?keyword=go%E8%AF%AD%E8%A8%80%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E8%BF%9B%E9%98%B6%E5%AE%9E%E6%88%98&amp;enc=utf-8&amp;suggest=1.def.0.V02&amp;wq=Go%E8%AF%AD%E8%A8%80%E4%BB%8E&amp;pvid=145d55a92cab4b07b71326f8beb1700b</span></a></div>
<img src ="http://www.cppblog.com/sunicdavy/aggbug/215887.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2018-08-29 11:16 <a href="http://www.cppblog.com/sunicdavy/archive/2018/08/29/215887.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Golang 热更新研究笔记</title><link>http://www.cppblog.com/sunicdavy/archive/2017/07/06/215057.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 06 Jul 2017 04:47:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2017/07/06/215057.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/215057.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2017/07/06/215057.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/215057.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/215057.html</trackback:ping><description><![CDATA[<p data-source-line="1" style="box-sizing: border-box; margin-bottom: 16px; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; line-height: 21px; widows: 1; background-color: #ffffff; margin-top: 0px !important;">本文主要研究游戏服务器带状态的热更新需求 http的无状态热更新需求已经有成熟方案, 故不在本文描述范围</p><h1><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#基本概念" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>基本概念</h1><ul data-source-line="6" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; padding-left: 2em; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; line-height: 21px; widows: 1; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">Golang的热更新采用什么机制?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">使用go1.8提供的plugin包机制实现</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">plugin包本身设计的目的是热更新么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">plugin包其实只是支持将代码分别编译为多个动态库,动态加载后运行 并不能完全支持类似C/C++的动态库方式处理代码</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">带状态的进程热更新的基本概念及范围是什么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">数据部分(model)不更新, 只更新逻辑部分(函数)</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">表格和配置更新算热更新么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">算, 但不是本文描述范围</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">热更新能在windows上使用么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">不支持</p></li></ul><h1><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#代码及结构" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>代码及结构</h1><ul data-source-line="29" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; padding-left: 2em; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; line-height: 21px; widows: 1; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">我能将原来一个exe的代码编译为so提供给plugin使用么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">可以, 但是必须仍然保留main包作为插件入口, 并在main包内添加提供给plugin调用入口.</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如果动态库中没有main包, 编译出的so能用么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">不能, 包必须包含main, 否则输出的是.a的文件, plugin包加载会报错</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">动态库中, 非main包的的代码修改能做热更新么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;"><span style="box-sizing: border-box; font-weight: 600;">不能</span>!(崩溃了吧, 我提了一个issue:&nbsp;<a href="https://github.com/golang/go/issues/20554" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none; background-color: transparent;">https://github.com/golang/go/issues/20554</a>)</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如果确实做了修改, 底层会报错: plugin was built with a different version of package</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">解决方法: 修改plugin包底层实现并重新编译 打开runtime/plugin.go, 注释以下代码 for _, pkghash := range md.pkghashes { if pkghash.linktimehash != *pkghash.runtimehash { return "", nil, pkghash.modulename } } 执行/usr/local/go/run.bash 重编译+测试</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">代码中哪些可以被更新? 方法可以被更新么? 闭包呢?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">只能更新拥有静态地址的结构.例如: 包级别函数(类似于静态函数)</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">例如: svc_0.so里有一个Foo函数, svc_1.so修改了Foo函数实现, 热更新可实现</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;"><span style="box-sizing: border-box; font-weight: 600;">闭包=函数+捕获变量</span>, 实际上是一个动态结构, 没有静态地址, 无法被更新</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">各种包级别变量, 结构体变量, 结构体方法, 局部变量均不能被热更新, 但是变量值不会被影响</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">新增结构可以被运行</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">使用结构体方法调用了包级别函数, 包级别函数能被更新么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">可以, 虽然方法不能被更新, 但方法被调用的包级别函数的地址是固定的, 所以可以被热更新</p></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">init包初始化函数能用么? 能被热更新么?</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">官方这样描述:</p><pre data-source-line="71" style="box-sizing: border-box; font-stretch: normal; font-size: 11.9px; line-height: 1.45; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; word-wrap: normal; margin-top: 0px; margin-bottom: 16px; padding: 16px; overflow: auto; border-radius: 3px; background-color: #f7f7f7;"><code style="box-sizing: border-box; display: inline; overflow: visible; padding: 0px; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; margin: 0px; font-size: 11.9px; border-radius: 3px; word-break: normal; border: 0px; line-height: inherit; word-wrap: normal; background: 0px 0px transparent;"><span style="box-sizing: border-box; font-weight: 700;">When</span> a plugin <span style="box-sizing: border-box; font-weight: 700;">is</span> first opened, the init functions <span style="box-sizing: border-box; font-weight: 700;">of</span> <span style="box-sizing: border-box; font-weight: 700;">all</span> packages <span style="box-sizing: border-box; font-weight: 700;">not</span> already part <span style="box-sizing: border-box; font-weight: 700;">of</span> the program are called. The main <span style="box-sizing: border-box; font-weight: 700;">function</span> <span style="box-sizing: border-box; font-weight: 700;">is</span> <span style="box-sizing: border-box; font-weight: 700;">not</span> run. A plugin <span style="box-sizing: border-box; font-weight: 700;">is</span> only initialized once, <span style="box-sizing: border-box; font-weight: 700;">and</span> cannot be closed</code></pre><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">插件第一次被打开时, 其关联的, 没有成为程序的一部分的所有的包的init函数将被调用. 插件的main函数不会被调用. 插件只会被初始化一次, 不能被关闭</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">因此, 需要手动将init函数改成自己的函数, 统一在so的main包里调用</p></li></ul><h1><a href="file:///C:/Users/Davy/AppData/Local/Youdao/YNote/markdown/index.html#编译" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none;"></a>编译</h1><ul data-source-line="80" style="box-sizing: border-box; margin-top: 0px; padding-left: 2em; color: #333333; font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; line-height: 21px; widows: 1; background-color: #ffffff; margin-bottom: 0px !important;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">如何编译获得plugin包支持的动态库</p><pre data-source-line="82" style="box-sizing: border-box; font-stretch: normal; font-size: 11.9px; line-height: 1.45; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; word-wrap: normal; margin-top: 0px; margin-bottom: 16px; padding: 16px; overflow: auto; border-radius: 3px; background-color: #f7f7f7;"><code style="box-sizing: border-box; display: inline; overflow: visible; padding: 0px; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; margin: 0px; font-size: 11.9px; border-radius: 3px; word-break: normal; border: 0px; line-height: inherit; word-wrap: normal; background: 0px 0px transparent;">SVCNAME=<span style="box-sizing: border-box; color: teal;">$1</span> SVCVER=<span style="box-sizing: border-box; color: teal;">$2</span> TIMESTAMP=`date <span style="box-sizing: border-box; color: #dd1144;">'+%Y%m%d_%H%M%S'</span>` go build -v -buildmode=plugin --ldflags=<span style="box-sizing: border-box; color: #dd1144;">"-pluginpath=${SVCNAME}_${TIMESTAMP}"</span> -o ${SVCNAME}<span style="box-sizing: border-box; color: teal;">_</span>${SVCVER}.so ${SVCNAME}</code></pre><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">-buildmode=plugin是重要参数</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">--ldflags里的-pluginpath的作用是: 每次编译的内部识别路径都是不同的, 避免重复加载的警告</p><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">参考:&nbsp;<a href="https://github.com/golang/go/issues/19004" style="box-sizing: border-box; color: #4078c0; text-decoration-line: none; background-color: transparent;">https://github.com/golang/go/issues/19004</a></p></li></ul><img src ="http://www.cppblog.com/sunicdavy/aggbug/215057.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2017-07-06 12:47 <a href="http://www.cppblog.com/sunicdavy/archive/2017/07/06/215057.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Visual Studio Code调试Golang工程</title><link>http://www.cppblog.com/sunicdavy/archive/2017/04/20/214874.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 20 Apr 2017 04:52:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2017/04/20/214874.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/214874.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2017/04/20/214874.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/214874.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/214874.html</trackback:ping><description><![CDATA[<h1 id="使用visual-studio-code调试golang工程" style="box-sizing: border-box; white-space: normal; word-spacing: 0px; border-bottom: rgb(238,238,238) 1px solid; text-transform: none; color: rgb(51,51,51); padding-bottom: 0.3em; font: 700 2.25em/1.2 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; margin: 0px 0px 16px; widows: 1; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="1">使用Visual Studio Code调试Golang工程</h1>
<h2 id="关键字" style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; border-bottom: rgb(238,238,238) 1px solid; text-transform: none; color: rgb(51,51,51); padding-bottom: 0.3em; font: 700 1.75em/1.225 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 1em; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="3"><a class="markdownIt-Anchor" style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="http://www.cppblog.com/sunicdavy/admin/EditPosts.aspx#关键字"></a>关键字</h2>
<ul style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; padding-left: 2em; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="4"><li style="box-sizing: border-box">最简单的调试攻略</li><li style="box-sizing: border-box">多项目调试, 适用个人开发和项目开发</li><li style="box-sizing: border-box">无需修改系统环境变量</li></ul>
<h2 id="准备vscode" style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; border-bottom: rgb(238,238,238) 1px solid; text-transform: none; color: rgb(51,51,51); padding-bottom: 0.3em; font: 700 1.75em/1.225 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 1em; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="8"><a class="markdownIt-Anchor" style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="http://www.cppblog.com/sunicdavy/admin/EditPosts.aspx#准备vscode"></a>准备VSCode</h2>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="10">在官网下载最新版的VSCode:</p>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="12"><a style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="https://code.visualstudio.com/">https://code.visualstudio.com/</a></p>
<h2 id="安装golang插件" style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; border-bottom: rgb(238,238,238) 1px solid; text-transform: none; color: rgb(51,51,51); padding-bottom: 0.3em; font: 700 1.75em/1.225 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 1em; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="14"><a class="markdownIt-Anchor" style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="http://www.cppblog.com/sunicdavy/admin/EditPosts.aspx#安装golang插件"></a>安装Golang插件</h2>
<ul style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; padding-left: 2em; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="15"><li style="box-sizing: border-box">
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">打开扩展面板</p>
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">VSCode-&gt;查看-&gt;扩展</p></li><li style="box-sizing: border-box">
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">找到Go插件 在搜索框里输入Go, 找到第二行写有 Rich Go language support for Visual Studio Code的插件, 点击安装</p>
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">注意不是排名最高的</p></li><li style="box-sizing: border-box">
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">重启编辑器</p></li></ul>
<h2 id="配置启动项" style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; border-bottom: rgb(238,238,238) 1px solid; text-transform: none; color: rgb(51,51,51); padding-bottom: 0.3em; font: 700 1.75em/1.225 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 1em; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="26"><a class="markdownIt-Anchor" style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="http://www.cppblog.com/sunicdavy/admin/EditPosts.aspx#配置启动项"></a>配置启动项</h2>
<ul style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; padding-left: 2em; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="27"><li style="box-sizing: border-box">
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">打开调试面板</p>
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">VSCode-&gt;查看-&gt;调试</p></li><li style="box-sizing: border-box">
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">添加调试目标</p>
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">在"没有调试"的下拉框中点击"添加配置.."</p></li><li style="box-sizing: border-box">
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">添加目标调试配置</p>
<p style="box-sizing: border-box; margin-bottom: 16px; margin-top: 16px">例子:</p><pre style="box-sizing: border-box; overflow: auto; word-wrap: normal; margin-bottom: 16px; padding-bottom: 16px; padding-top: 16px; font: 11px/1.45 Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding-left: 16px; margin-top: 0px; padding-right: 16px; background-color: rgb(247,247,247); font-stretch: normal; border-radius: 3px" data-source-line="38"><code class="hljs" style="box-sizing: border-box; word-wrap: normal; font-size: 11px; border-top: 0px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; border-right: 0px;background: 0px 0px; white-space: pre; border-bottom: 0px; word-break: normal; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px; border-radius: 3px">{
    "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">version</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"0.2.0"</span></span>,
    "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">configurations</span>": <span class="hljs-value" style="box-sizing: border-box">[
        {
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">name</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"Launch"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">type</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"go"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">request</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"launch"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">mode</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"debug"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">remotePath</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">""</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">port</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-number" style="box-sizing: border-box; color: teal">2345</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">host</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"127.0.0.1"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">program</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"${fileDirname}"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">env</span>": <span class="hljs-value" style="box-sizing: border-box">{
                "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">GOPATH</span>":<span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"D:/Develop/vscodegolang"</span>
            </span>}</span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">args</span>": <span class="hljs-value" style="box-sizing: border-box">[]</span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">showLog</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-literal" style="box-sizing: border-box">true</span>
        </span>}
    ]
</span>}</code></pre></li></ul>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="61">其中: "port", "host"都是go插件自动生成的</p>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="63">"env"为设置环境变量, 设置为你的工程目录就可以(包含bin, src的文件夹)</p>
<h2 id="准备调试插件" style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; border-bottom: rgb(238,238,238) 1px solid; text-transform: none; color: rgb(51,51,51); padding-bottom: 0.3em; font: 700 1.75em/1.225 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 1em; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="66"><a class="markdownIt-Anchor" style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="http://www.cppblog.com/sunicdavy/admin/EditPosts.aspx#准备调试插件"></a>准备调试插件</h2>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="70">此时找到main.go按F5, 会报错提示:</p><pre style="box-sizing: border-box; overflow: auto; word-wrap: normal; margin-bottom: 16px; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 16px; padding-top: 16px; font: 11px/1.45 Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding-left: 16px; widows: 1; margin-top: 0px; letter-spacing: normal; padding-right: 16px; background-color: rgb(247,247,247); text-indent: 0px; -webkit-text-stroke-width: 0px; font-stretch: normal; border-radius: 3px" data-source-line="71"><code class="hljs" style="box-sizing: border-box; word-wrap: normal; font-size: 11px; border-top: 0px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; border-right: 0px;background: 0px 0px; white-space: pre; border-bottom: 0px; word-break: normal; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px; border-radius: 3px">Failded to continue:"Cannot find Delve debugger. <span class="hljs-operator" style="box-sizing: border-box"><span class="hljs-keyword" style="box-sizing: border-box; font-weight: 700; color: rgb(51,51,51)">Install</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: 700; color: rgb(51,51,51)">from</span> https://github.com/derekparker/delve &amp; ensure it <span class="hljs-keyword" style="box-sizing: border-box; font-weight: 700; color: rgb(51,51,51)">is</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: 700; color: rgb(51,51,51)">in</span> your <span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"GOPATH/bin"</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: 700; color: rgb(51,51,51)">or</span> <span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"PATH"</span></span></code></pre>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="75">我们使用go命令行编译调试器</p><pre style="box-sizing: border-box; overflow: auto; word-wrap: normal; margin-bottom: 16px; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 16px; padding-top: 16px; font: 11px/1.45 Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding-left: 16px; widows: 1; margin-top: 0px; letter-spacing: normal; padding-right: 16px; background-color: rgb(247,247,247); text-indent: 0px; -webkit-text-stroke-width: 0px; font-stretch: normal; border-radius: 3px" data-source-line="76"><code class="hljs" style="box-sizing: border-box; word-wrap: normal; font-size: 11px; border-top: 0px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; border-right: 0px;background: 0px 0px; white-space: pre; border-bottom: 0px; word-break: normal; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px; border-radius: 3px"><span class="hljs-keyword" style="box-sizing: border-box; font-weight: 700; color: rgb(51,51,51)">go</span> <span class="hljs-built_in" style="box-sizing: border-box; color: rgb(0,134,179)">get</span> github.<span class="hljs-keyword" style="box-sizing: border-box; font-weight: 700; color: rgb(51,51,51)">com</span>/derekparker/delve/cmd/dlv</code></pre>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="80">将dlv调试器放在GOPATH(工程目录)的bin目录下</p>
<h2 id="开始调试" style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; border-bottom: rgb(238,238,238) 1px solid; text-transform: none; color: rgb(51,51,51); padding-bottom: 0.3em; font: 700 1.75em/1.225 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 1em; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="82"><a class="markdownIt-Anchor" style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="http://www.cppblog.com/sunicdavy/admin/EditPosts.aspx#开始调试"></a>开始调试</h2>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="84">选中要调试的main.go, 点击F5, 既可以开始调试</p>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="86">调试快捷键和Visual Studio系一致</p>
<ul style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; padding-left: 2em; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="87"><li style="box-sizing: border-box">F9 切换断点</li><li style="box-sizing: border-box">F10 Step over</li><li style="box-sizing: border-box">F11 Step in</li><li style="box-sizing: border-box">Shift+F11 Step out</li></ul>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="92">注意点</p>
<ul style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; padding-left: 2em; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="93"><li style="box-sizing: border-box">某些结构体成员无法直接显示时, 可以直接选中变量名, 添加到监视, 或者右键点击: "调试:求值"</li></ul>
<h2 id="多项目调试" style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; border-bottom: rgb(238,238,238) 1px solid; text-transform: none; color: rgb(51,51,51); padding-bottom: 0.3em; font: 700 1.75em/1.225 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 1em; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="96"><a class="markdownIt-Anchor" style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="http://www.cppblog.com/sunicdavy/admin/EditPosts.aspx#多项目调试"></a>多项目调试</h2>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="98">在launch.json中可以添加多组调试入口, 通过调试面板中选中对应的配置开启不同目标的调试</p><pre style="box-sizing: border-box; overflow: auto; word-wrap: normal; margin-bottom: 16px; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); padding-bottom: 16px; padding-top: 16px; font: 11px/1.45 Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding-left: 16px; widows: 1; margin-top: 0px; letter-spacing: normal; padding-right: 16px; background-color: rgb(247,247,247); text-indent: 0px; -webkit-text-stroke-width: 0px; font-stretch: normal; border-radius: 3px" data-source-line="100"><code class="hljs" style="box-sizing: border-box; word-wrap: normal; font-size: 11px; border-top: 0px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; border-right: 0px;background: 0px 0px; white-space: pre; border-bottom: 0px; word-break: normal; color: rgb(51,51,51); padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px; border-radius: 3px">{
    "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">version</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"0.2.0"</span></span>,
    "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">configurations</span>": <span class="hljs-value" style="box-sizing: border-box">[
        {
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">name</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"client"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">type</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"go"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">request</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"launch"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">mode</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"debug"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">remotePath</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">""</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">port</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-number" style="box-sizing: border-box; color: teal">2345</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">host</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"127.0.0.1"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">program</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"${fileDirname}"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">env</span>": <span class="hljs-value" style="box-sizing: border-box">{
                "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">GOPATH</span>":<span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"D:/Develop/vscodegolang"</span>
            </span>}</span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">args</span>": <span class="hljs-value" style="box-sizing: border-box">[]</span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">showLog</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-literal" style="box-sizing: border-box">true</span>
        </span>},

        {
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">name</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"server"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">type</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"go"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">request</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"launch"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">mode</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"debug"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">remotePath</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">""</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">port</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-number" style="box-sizing: border-box; color: teal">2345</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">host</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"127.0.0.1"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">program</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"${workspaceRoot}/src/server"</span></span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">env</span>": <span class="hljs-value" style="box-sizing: border-box">{
                "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">GOPATH</span>":<span class="hljs-value" style="box-sizing: border-box"><span class="hljs-string" style="box-sizing: border-box; color: rgb(221,17,68)">"D:/Develop/vscodegolang"</span>
            </span>}</span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">args</span>": <span class="hljs-value" style="box-sizing: border-box">[]</span>,
            "<span class="hljs-attribute" style="box-sizing: border-box; color: teal">showLog</span>": <span class="hljs-value" style="box-sizing: border-box"><span class="hljs-literal" style="box-sizing: border-box">true</span>
        </span>}
    ]
</span>}</code></pre>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="138">"program"中的"${fileDirname}"是以当前选中文件作为启动点</p>
<p style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="140"><strong style="box-sizing: border-box; font-weight: bolder">更建议使用"program"的"${workspaceRoot}", 以包名作为启动点的方式进行配置</strong></p>
<h2 id="参考链接" style="box-sizing: border-box; margin-bottom: 16px; white-space: normal; word-spacing: 0px; border-bottom: rgb(238,238,238) 1px solid; text-transform: none; color: rgb(51,51,51); padding-bottom: 0.3em; font: 700 1.75em/1.225 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 1em; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="144"><a class="markdownIt-Anchor" style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="http://www.cppblog.com/sunicdavy/admin/EditPosts.aspx#参考链接"></a>参考链接</h2>
<p style="box-sizing: border-box; margin-bottom: 0px !important; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font: 14px/22px 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; widows: 1; margin-top: 0px; letter-spacing: normal; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px" data-source-line="146"><a style="box-sizing: border-box; text-decoration: none; color: rgb(64,120,192); background-color: transparent" href="https://code.visualstudio.com/Docs/editor/debugging">https://code.visualstudio.com/Docs/editor/debugging</a></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/214874.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2017-04-20 12:52 <a href="http://www.cppblog.com/sunicdavy/archive/2017/04/20/214874.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Go语言与构造函数</title><link>http://www.cppblog.com/sunicdavy/archive/2016/12/01/214457.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 01 Dec 2016 02:45:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2016/12/01/214457.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/214457.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2016/12/01/214457.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/214457.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/214457.html</trackback:ping><description><![CDATA[<p style="margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-top: 0px !important;">Golang中没有设计构造函数. 取而代之的, 设计Golang的大师希望你用普通函数去实现构造的任务.&nbsp;<br />一直只是觉得这只是体现Golang这门新语言的精简设计之道, 直到自己实现编译器后才发现构造函数的设计本身是值得商榷的</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">我们先看下构造函数的规则</p><h1>构造函数调用规则</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">构造参数量: 0表示没有构造函数, 1表示有构造函数0个参数</p><table style="margin: 10px 0px; border-collapse: collapse; border-style: solid; border-color: #bbbbbb; padding: 0px; color: #000000; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><thead><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><th style="padding: 6px 13px; border-collapse: collapse; border: 1px solid #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">本类构造</th><th style="padding: 6px 13px; border-collapse: collapse; border: 1px solid #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">父类构造</th><th style="padding: 6px 13px; border-collapse: collapse; border: 1px solid #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">处理方法</th></tr></thead><tbody><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">0</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">0</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">不处理</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: #f8f8f8;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">0</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">调本类ctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">0</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">调父类ctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: #f8f8f8;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">调本类ctor, 本类ctor调父类ctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">2</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">调本类ctor, 本类ctor调父类ctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: #f8f8f8;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">1</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">2</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">报错, 手动调父类ctor</td></tr><tr style="border-top-width: 1px; border-top-style: solid; border-top-color: #cccccc; margin: 0px; padding: 0px; background-color: white;"><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">2</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">2</td><td style="padding: 6px 13px; border-collapse: collapse; border-style: solid; border-color: #cccccc; height: 28px; word-break: break-all; box-sizing: border-box; outline: none; margin: 0px; font-size: 14px;">报错, 手动调父类ctor</td></tr></tbody></table><h1>普通函数重载规则</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">实际只用考虑最典型的一种行为: 实例化子类, 转为父类调用方法, 这个时候</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">如果方法是override, 调用的是子类</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">如果方法是virutal或者不指明, 调用的是父类</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">整个重载过程, 子类绝对不会隐式调用父类的行为</p><h1>需要构造函数么?</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">构造函数的优点</p><ul style="margin: 10px 0px; padding-left: 32px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><li style="margin: 0px 0px 5px;">本身属于一种特殊的成员函数</li><li style="margin: 5px 0px;">编译器帮你自动传导调用父级</li></ul><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">构造函数的缺点</p><ul style="margin: 10px 0px; padding-left: 32px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><li style="margin: 0px 0px 5px;">隐式的调用规则</li><li style="margin: 5px 0px;">虽然属于成员函数, 但是与其他成员函数调用规则完全不同, 需要特殊记忆</li><li style="margin: 5px 0px;">带参数的构造函数, 在父类参数多于子类时, 需要引用复杂语法来实现父级构造调用</li></ul><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">其实我们对初始化函数的需求只有1条: 自定义</p><p style="margin-top: 10px; margin-right: 0px; margin-left: 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-bottom: 0px !important;">所以, 可以理解Golang不加入构造函数的设计是正确的&nbsp;<br />即: 简单, 清晰, 有规律</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/214457.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2016-12-01 10:45 <a href="http://www.cppblog.com/sunicdavy/archive/2016/12/01/214457.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Go语言的冷知识</title><link>http://www.cppblog.com/sunicdavy/archive/2016/11/02/214375.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 02 Nov 2016 03:09:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2016/11/02/214375.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/214375.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2016/11/02/214375.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/214375.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/214375.html</trackback:ping><description><![CDATA[<h1>append, map, len不是关键字</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">他们其实还是类库功能, 都在buildin包里的, 系统默认给你做了个</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #1e347b; margin-top: 0px;">import</span><span style="color: #93a1a1;">(</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"> <span style="color: #93a1a1;">.</span> <span style="color: #dd1144;">"buildin"</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">)</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">将buildin的包内容都映射到全局而已, 其实你也可以用自己的包这么做</p><h1>打印的另一种写法</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">想跟脚本一样调试打印数据么?</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">println</span><span style="color: #93a1a1;">(</span><span style="color: #dd1144;">"hello world"</span><span style="color: #93a1a1;">)</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">无需包含任何包, 因为它在buildin包里</p><h1>iota不是黑科技</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">这是在buildin包里的定义</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">// iota is a predeclared identifier representing the untyped integer ordinal</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">// number of the current const specification in a (usually parenthesized)</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">// const declaration. It is zero-indexed.</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #1e347b; margin-top: 0px;">const</span><span style="color: #48484c;"> iota </span><span style="color: #93a1a1;">=</span> <span style="color: #195f91;">0</span> <span style="color: #93a1a1;">// Untyped int.</span></code></li></ol></pre><h1>其实go是有泛型概念的</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">想想map和数组的定义&nbsp;<br />只是泛型没有开放给用户用而已(只许XX放火,不许XX点灯)</p><h1>map是支持多个key的, 而且很方便</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">还在为多个key转id的复杂算法而头疼么?</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">type myKey </span><span style="color: #1e347b;">struct</span><span style="color: #93a1a1;">{</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    number </span><span style="color: #1e347b;">int</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    str </span><span style="color: #1e347b;">string</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">func main</span><span style="color: #93a1a1;">(){</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    t </span><span style="color: #93a1a1;">:=</span><span style="color: #48484c;"> map</span><span style="color: #93a1a1;">[</span><span style="color: #48484c;"> myKey</span><span style="color: #93a1a1;">]</span> <span style="color: #1e347b;">int</span> <span style="color: #93a1a1;">{</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">        myKey</span><span style="color: #93a1a1;">{</span> <span style="color: #195f91;">2</span><span style="color: #93a1a1;">,</span> <span style="color: #dd1144;">"world"</span><span style="color: #93a1a1;">}:</span> <span style="color: #195f91;">1</span><span style="color: #93a1a1;">,</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"> <span style="color: #93a1a1;">}</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    fmt</span><span style="color: #93a1a1;">.</span><span style="color: teal;">Println</span><span style="color: #93a1a1;">(</span><span style="color: #48484c;">t</span><span style="color: #93a1a1;">[</span><span style="color: #48484c;">myKey</span><span style="color: #93a1a1;">{</span><span style="color: #195f91;">2</span><span style="color: #93a1a1;">,</span> <span style="color: #dd1144;">"world"</span><span style="color: #93a1a1;">}])</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">输出:</span> <span style="color: #195f91;">1</span></code></li></ol></pre><h1>枚举是可以转成string的</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">默认定义一个枚举</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">type </span><span style="color: teal;">MyConst</span> <span style="color: #1e347b;">int</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #1e347b; margin-top: 0px;">const</span> <span style="color: #93a1a1;">(</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"> <span style="color: teal;">MyConst_A</span> <span style="color: teal;">MyConst</span> <span style="color: #93a1a1;">=</span><span style="color: #48484c;"> iota</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"> <span style="color: teal;">MyConst_B</span> <span style="color: teal;">MyConst</span> <span style="color: #93a1a1;">=</span><span style="color: #48484c;"> iota</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">)</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">func main</span><span style="color: #93a1a1;">(){</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    fmt</span><span style="color: #93a1a1;">.</span><span style="color: teal;">Println</span><span style="color: #93a1a1;">(</span><span style="color: teal;">MyConst_A</span><span style="color: #93a1a1;">)</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">输出: 0&nbsp;<br />如果我们想自动化输出MyConst_A字符串时&nbsp;<br />就需要使用golang的一个工具链:golang.org/x/tools/cmd/stringer&nbsp;<br />将其下载, 编译成可执行工具后, 对代码进行生成&nbsp;<br />生成的代码会多出一个xx_string.go&nbsp;<br />里面就是枚举的String()string 函数</p><h1>临时转换一个接口并调用的方法</h1><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">type love </span><span style="color: #1e347b;">struct</span><span style="color: #93a1a1;">{</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">func </span><span style="color: #93a1a1;">(</span><span style="color: #1e347b;">self</span><span style="color: #93a1a1;">*</span><span style="color: #48484c;">love</span><span style="color: #93a1a1;">)</span><span style="color: #48484c;">foo</span><span style="color: #93a1a1;">(){</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    fmt</span><span style="color: #93a1a1;">.</span><span style="color: teal;">Println</span><span style="color: #93a1a1;">(</span><span style="color: #dd1144;">"love"</span><span style="color: #93a1a1;">)</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">func main</span><span style="color: #93a1a1;">(){</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"> <span style="color: #1e347b;">var</span><span style="color: #48484c;"> chaos </span><span style="color: #1e347b;">interface</span><span style="color: #93a1a1;">{}</span> <span style="color: #93a1a1;">=</span> <span style="color: #1e347b;">new</span><span style="color: #93a1a1;">(</span><span style="color: #48484c;">love</span><span style="color: #93a1a1;">)</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    chaos</span><span style="color: #93a1a1;">.(</span><span style="color: #1e347b;">interface</span><span style="color: #93a1a1;">{</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">        foo</span><span style="color: #93a1a1;">()</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"> <span style="color: #93a1a1;">}).</span><span style="color: #48484c;">foo</span><span style="color: #93a1a1;">()</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li></ol></pre><h1>Golang的receiver实际上就是this的变种实现</h1><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">func</span><span style="color: #93a1a1;">(</span> <span style="color: #1e347b;">self</span><span style="color: #93a1a1;">*</span><span style="color: teal;">MyStruct</span><span style="color: #93a1a1;">)</span><span style="color: #48484c;"> foo</span><span style="color: #93a1a1;">(</span><span style="color: #48484c;"> p </span><span style="color: #1e347b;">int</span> <span style="color: #93a1a1;">){</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">写不惯receiver的写法? 如果这样改下呢?</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">func foo</span><span style="color: #93a1a1;">(</span> <span style="color: #1e347b;">self</span> <span style="color: #93a1a1;">*</span><span style="color: teal;">MyStruct</span><span style="color: #93a1a1;">,</span><span style="color: #48484c;"> p </span><span style="color: #1e347b;">int</span> <span style="color: #93a1a1;">){</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">所以为什么说Golang还是一个C语言嘛</p><h1>关于内存分配&#8230;</h1><ul style="margin: 10px 0px; padding-left: 32px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><li style="margin: 0px 0px 5px;">new 传入Type类型, 返回*Type类型</li><li style="margin: 5px 0px;">make 可以在分配数组时设置预分配大小, new不可以</li><li style="margin: 5px 0px;">make 能分配数组,map, 但不能分配结构体和原始类型</li><li style="margin: 5px 0px;">new 能分配数组, map, 结构体和原始类型等的所有类型</li><li style="margin: 5px 0px;">&amp;Type等效于new</li><li style="margin: 5px 0px;">切片不需要分配内存(make,new), 直接声明就可以了&#8230;</li></ul><h1>Golang的反射无法通过一个类型名, 创建其实例</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">C#有Assembly概念, 可以在一个Assembly里搜索, 创建实例</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">Golang是静态类型语言, 如果需要, 只能注册你需要创建的结构体, 然后将注册好的map用于创建</p><h1>Golang可以替换Python来进行复杂的工具流程处理</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">如果你需要跨平台的工具流程处理, 对Python不熟悉, 可以使用</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">go run yourcode</span><span style="color: #93a1a1;">.</span><span style="color: #48484c;">go </span><span style="color: #93a1a1;">参数</span><span style="color: #195f91;">1</span> <span style="color: #93a1a1;">参数</span><span style="color: #195f91;">2</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">方式来进行工具处理&nbsp;<br />觉得慢, 可以编译成可执行文件</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">这样做的好处: 如果有些类库本身就是go写的, Python想使用是很麻烦的, 而Golang来写则轻而易举</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">例子: 通过go的protobuf库, 对一些文件进行处理</p><h1>Golang可以自动持有方法的接收者实例</h1><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">type myType </span><span style="color: #1e347b;">struct</span><span style="color: #93a1a1;">{</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">func </span><span style="color: #93a1a1;">(</span><span style="color: #1e347b;">self</span><span style="color: #93a1a1;">*</span><span style="color: #48484c;">myType</span><span style="color: #93a1a1;">)</span><span style="color: #48484c;"> foo</span><span style="color: #93a1a1;">(</span><span style="color: #48484c;"> p </span><span style="color: #1e347b;">int</span><span style="color: #93a1a1;">){</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    fmt</span><span style="color: #93a1a1;">.</span><span style="color: teal;">Println</span><span style="color: #93a1a1;">(</span><span style="color: #dd1144;">"hello"</span><span style="color: #93a1a1;">,</span><span style="color: #48484c;"> p </span><span style="color: #93a1a1;">)</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">func main</span><span style="color: #93a1a1;">(){</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"> <span style="color: #1e347b;">var</span><span style="color: #48484c;"> callback func</span><span style="color: #93a1a1;">(</span> <span style="color: #1e347b;">int</span> <span style="color: #93a1a1;">)</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    ins </span><span style="color: #93a1a1;">:=</span> <span style="color: #1e347b;">new</span><span style="color: #93a1a1;">(</span><span style="color: #48484c;">myType</span><span style="color: #93a1a1;">)</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    callback </span><span style="color: #93a1a1;">=</span><span style="color: #48484c;"> ins</span><span style="color: #93a1a1;">.</span><span style="color: #48484c;">foo</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">    callback</span><span style="color: #93a1a1;">(</span> <span style="color: #195f91;">100</span> <span style="color: #93a1a1;">)</span></code></li><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #93a1a1; margin-top: 0px;">}</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">做过lua的C++代码绑定的童鞋都清楚: lua只支持外部静态或者全局函数调用&nbsp;<br />如果要进行C++类成员函数调用时, 要自己处理this和成员函数&nbsp;<br />这种技巧因为早起编译器的虚表不同平台实现细节不统一需要专门处理&nbsp;<br />后面跨平台虚表统一后, 类成员函数的调用写法也是很恶心复杂的&nbsp;<br />但是Golang的小白式用法, 直接吊打C++, 甚至C#复杂的delegate</p><h1>LiteIDE篇: 多开秘籍</h1><ul style="margin: 10px 0px; padding-left: 32px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><li style="margin: 0px 0px 5px;"><p style="margin: 0px;">找到 菜单-&gt;查看-&gt;选项-&gt;通用-&gt;存储-&gt;存储设置到本地ini文件</p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">关闭LiteIDE</p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">复制LiteIDE整个目录, 命名文件夹为你的工程名</p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">每个工程所在的LiteIDE的配置将是独立的, 不会互相干扰</p></li></ul><h1>LiteIDE篇: 测试程序也是可以调试的</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">别以为程序一定要是main开始的才可以调试</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">Golang的测试程序虽然都是一个个Test开头的函数,但执行go test时, 还是有main入口</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">在LiteIDE中, 可以在 调试-&gt;开始调试测试程序里进行测试程序调试</p><h1>LiteIDE篇: 在Windows上可以输出linux可执行文件</h1><p style="margin-top: 10px; margin-right: 0px; margin-left: 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-bottom: 0px !important;">go的工具链默认支持交叉编译&nbsp;<br />在LiteIDE中, 可以通过切换输出平台, 输出不同平台的可执行文件</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/214375.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2016-11-02 11:09 <a href="http://www.cppblog.com/sunicdavy/archive/2016/11/02/214375.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用delve调试Golang程序技巧</title><link>http://www.cppblog.com/sunicdavy/archive/2016/09/03/214254.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Sat, 03 Sep 2016 10:12:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2016/09/03/214254.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/214254.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2016/09/03/214254.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/214254.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/214254.html</trackback:ping><description><![CDATA[<p style="margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-top: 0px !important;"></p><p style="margin-right: 0px; margin-bottom: 10px; margin-left: 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-top: 0px !important;">Google官方为Golang的调试例子默认使用了gdb</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">然而, 使用gdb调试go程序会遇到goroutine的各类问题, 因为gdb不懂go</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">因此, 这里使用delve黑科技来进行Golang的程序调试</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">纯命令行调试方法在网上很容易搜索到, 本文主要以LiteIDE来进行程序调试</p><h1>关闭编译器优化</h1><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">正常go build/install出的go程序是完全优化过的, 强行使用调试器挂接调试时, 某些local变量/lamda表达式捕获的变量会直接进入寄存器, 无法使用调试器查看</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">删掉所有的pkg, 为build或install参数加入关闭编译器优化的参数 -gcflags "-N -l"</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">例如:</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">   go install </span><span style="color: #93a1a1;">-</span><span style="color: #48484c;">gcflags </span><span style="color: #dd1144;">"-N -l"</span><span style="color: #48484c;"> svc\gamesvc</span></code></li></ol></pre><h2>delve调试器安装方法</h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">LiteIDE自带了gdb, 但是没有delve调试器, 需要自行安装, 命令如下</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">go </span><span style="color: #1e347b;">get</span><span style="color: #48484c;"> github</span><span style="color: #93a1a1;">.</span><span style="color: #48484c;">com</span><span style="color: #93a1a1;">/</span><span style="color: #48484c;">derekparker</span><span style="color: #93a1a1;">/</span><span style="color: #48484c;">delve</span><span style="color: #93a1a1;">/</span><span style="color: #48484c;">cmd</span><span style="color: #93a1a1;">/</span><span style="color: #48484c;">dlv</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">delve调试器会被放到你的GOPATH/bin下</p><h1>LiteIDE中的delve调试器配置</h1><h2>选择调试器</h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">在LiteIDE菜单中选择 调试-&gt;debugger/delve</p><h2>delve环境变量设置</h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">这个时候, LiteIDE依然找不到delve, 因为它不在环境变量PATH中, 这里无需修改环境变量, 只需要LiteIDE的环境配置</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">在LiteIDE菜单中选择 查看-&gt;编辑当前环境, 在弹出的文档中修改</p><pre linenums=""  prettyprinted"="" style="margin-top: 10px; margin-bottom: 10px; border: 1px solid #e1e1e8; font-size: 13px; line-height: 19px; overflow: auto; padding: 10px; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; box-shadow: #fbfbfc 40px 0px 0px inset, #ececf0 41px 0px 0px inset; widows: 1; background-color: #f7f7f9;"><ol style="margin: 0px; padding-left: 30px !important; color: #1e347b;"><li style="margin: 0px; color: #bebec5; line-height: 18px; padding-left: 12px !important; list-style-type: decimal !important;"><code style="margin: 0px; padding: 0px; border: none; border-radius: 3px; word-wrap: break-word; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; max-width: 100%; background: transparent;"><span style="color: #48484c; margin-top: 0px;">PATH</span><span style="color: #93a1a1;">=</span><span style="color: #48484c;">c</span><span style="color: #93a1a1;">:</span><span style="color: #48484c;">\mingw32\b</span><span style="color: #1e347b;">in</span><span style="color: #93a1a1;">;%</span><span style="color: #48484c;">GOROOT</span><span style="color: #93a1a1;">%</span><span style="color: #48484c;">\b</span><span style="color: #1e347b;">in</span><span style="color: #93a1a1;">;%</span><span style="color: #48484c;">PATH</span><span style="color: #93a1a1;">%;</span><span style="color: #48484c;">c</span><span style="color: #93a1a1;">:</span><span style="color: #48484c;">\y</span><span style="color: #1e347b;">our</span><span style="color: #48484c;">\path\to\delve</span></code></li></ol></pre><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">去掉PATH前的注释#, 在%PATH%添加分号, 然后和你到delve调试器的路径</p><h2>开始调试</h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">选择你的工程, 点击F5, 进入调试模式</p><h2>调试器显示变量值</h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;"><img src="file:///D:/Documents/My%20Knowledge/temp/6f9eec62-fe6c-4f28-89ad-acbade688a96/4/index_files/2be001ea-878e-4e38-9209-76ef93d427f0.png" style="border: 0px; max-width: 100%; margin: 2px 0px; height: auto !important;"  alt="" /></p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">LiteIDE使用delve调试时, 无法在 变量 监视等窗口中正确捕捉delve调试返回数据(因为格式太复杂了&#8230;)</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">没关系, 我们使用命令行配合显示即可</p><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">LiteIDE控制台或调试输出窗口在delve调试时, 实际上是一个标准命令行&nbsp;<br />命令如下</p><ul style="margin: 10px 0px; padding-left: 32px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; font-size: 15px; line-height: 24px; widows: 1;"><li style="margin: 0px 0px 5px;"><p style="margin: 0px;">p 变量名可以查看变量值</p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">locals查看局部变量</p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">ls可查看当前文件</p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">stack查看栈</p></li><li style="margin: 5px 0px;"><p style="margin: 0px;">help可以查看各种帮助</p></li></ul><h2>调试外部程序</h2><p style="margin: 10px 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1;">如果你的程序是外部程序, 或者使用go install安装到GOPATH/bin目录的程序, 那么使用delve调试器启动程序时, 可能会碰到启动路径错误的问题</p><p style="margin-top: 10px; margin-right: 0px; margin-left: 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-bottom: 0px !important;">使用LiteIDE菜单 调试-&gt;调试其他应用程序&#8230; 填入你要调试程序的路径以及工作目录, 可以解决这个问题</p><p style="margin-top: 10px; margin-right: 0px; margin-left: 0px; font-size: 15px; font-family: Helvetica, &quot;Hiragino Sans GB&quot;, 微软雅黑, &quot;Microsoft YaHei UI&quot;, SimSun, SimHei, arial, sans-serif; line-height: 24px; widows: 1; margin-bottom: 0px !important;"></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/214254.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2016-09-03 18:12 <a href="http://www.cppblog.com/sunicdavy/archive/2016/09/03/214254.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Golang的简单反射性能测试</title><link>http://www.cppblog.com/sunicdavy/archive/2016/08/12/214152.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 12 Aug 2016 07:26:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2016/08/12/214152.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/214152.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2016/08/12/214152.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/214152.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/214152.html</trackback:ping><description><![CDATA[<h3>测试用例</h3> <p>我们对Golang的结构体变量赋值, 以及单参数函数调用进行反射和native操作的测试<pre><p><p><code>&nbsp;</code></p><p><code>package main</code></p><p><code>&nbsp;</code></p><p><code>import (</code></p><p><code>    "reflect"</code></p><p><code>    "testing"</code></p><p><code>)</code></p><p><code>&nbsp;</code></p><p><code>type data struct {</code></p><p><code>    Hp int</code></p><p><code>}</code></p><p><code>&nbsp;</code></p><p><code>const AssignTimes = 100000000</code></p><p><code>&nbsp;</code></p><p><code>func TestNativeAssign(t *testing.T) {</code></p><p><code>&nbsp;</code></p><p><code>    v := data{Hp: 2}</code></p><p><code>&nbsp;</code></p><p><code>    for i := 0; i &lt; AssignTimes; i++ {</code></p><p><code>        v.Hp = 3</code></p><p><code>    }</code></p><p><code>&nbsp;</code></p><p><code>}</code></p><p><code>&nbsp;</code></p><p><code>func TestReflectAssign(t *testing.T) {</code></p><p><code>&nbsp;</code></p><p><code>    v := data{Hp: 2}</code></p><p><code>&nbsp;</code></p><p><code>    vv := reflect.ValueOf(&amp;v).Elem()</code></p><p><code>&nbsp;</code></p><p><code>    f := vv.FieldByName("Hp")</code></p><p><code>&nbsp;</code></p><p><code>    for i := 0; i &lt; AssignTimes; i++ {</code></p><p><code>&nbsp;</code></p><p><code>        f.SetInt(3)</code></p><p><code>    }</code></p><p><code>&nbsp;</code></p><p><code>}</code></p><p><code>&nbsp;</code></p><p><code>func TestReflectFindFieldAndAssign(t *testing.T) {</code></p><p><code>&nbsp;</code></p><p><code>    v := data{Hp: 2}</code></p><p><code>&nbsp;</code></p><p><code>    vv := reflect.ValueOf(&amp;v).Elem()</code></p><p><code>&nbsp;</code></p><p><code>    for i := 0; i &lt; AssignTimes; i++ {</code></p><p><code>&nbsp;</code></p><p><code>        vv.FieldByName("Hp").SetInt(3)</code></p><p><code>    }</code></p><p><code>&nbsp;</code></p><p><code>}</code></p><p><code>&nbsp;</code></p><p><code>func foo(v int) {</code></p><p><code>&nbsp;</code></p><p><code>}</code></p><p><code>&nbsp;</code></p><p><code>const CallTimes = 100000000</code></p><p><code>&nbsp;</code></p><p><code>func TestNativeCall(t *testing.T) {</code></p><p><code>    for i := 0; i &lt; CallTimes; i++ {</code></p><p><code>&nbsp;</code></p><p><code>        foo(i)</code></p><p><code>    }</code></p><p><code>}</code></p><p><code>&nbsp;</code></p><p><code>func TestReflectCall(t *testing.T) {</code></p><p><code>&nbsp;</code></p><p><code>    v := reflect.ValueOf(foo)</code></p><p><code>&nbsp;</code></p><p><code>    for i := 0; i &lt; CallTimes; i++ {</code></p><p><code>&nbsp;</code></p><p><code>        v.Call([]reflect.Value{reflect.ValueOf(2)})</code></p><p><code>    }</code></p><p><code>}</code></p></pre>
<h3>性能测试数据</h3>
<p>=== RUN TestNativeAssign<br>— PASS: TestNativeAssign (0.03s)<br>=== RUN TestReflectAssign<br>— PASS: TestReflectAssign (0.41s)<br>=== RUN TestReflectFindFieldAndAssign<br>— PASS: TestReflectFindFieldAndAssign (9.86s)<br>=== RUN TestNativeCall<br>— PASS: TestNativeCall (0.03s)<br>=== RUN TestReflectCall<br>— PASS: TestReflectCall (21.46s)
<h3>测试评测</h3>
<ul>
<li>在结构体变量赋值测试用例中, 我们发现TestReflectFindFieldAndAssign赋值格外的耗时. 分析性能点在FieldByName这个函数上, 我们查了下底层如何实现的:</li></ul><pre><p><p><code>// FieldByName returns the struct field with the given name</code></p><p><code>// and a boolean to indicate if the field was found.</code></p><p><code>func (t *structType) FieldByName(name string) (f StructField, present bool) {</code></p><p><code>    // Quick check for top-level name, or struct without anonymous fields.</code></p><p><code>    hasAnon := false</code></p><p><code>    if name != "" {</code></p><p><code>        for i := range t.fields {</code></p><p><code>            tf := &amp;t.fields[i]</code></p><p><code>            if tf.name == nil {</code></p><p><code>                hasAnon = true</code></p><p><code>                continue</code></p><p><code>            }</code></p><p><code>            if *tf.name == name {</code></p><p><code>                return t.Field(i), true</code></p><p><code>            }</code></p><p><code>        }</code></p><p><code>    }</code></p><p><code>    if !hasAnon {</code></p><p><code>        return</code></p><p><code>    }</code></p><p><code>    return t.FieldByNameFunc(func(s string) bool { return s == name })</code></p><p><code>}</code></p></pre>
<p>各位看官必须吐槽用for来遍历获取数据, 但冷静下来分析. 这样做无可厚非.<br>试想如果reflect包在我们使用ValueOf时使用map缓冲好一个结构体所有字段的访问数据后, 肯定访问指定字段速度会很快<br>但是, 以空间换速度的需求其实最多满足了1%的需求.<br>同样的例子是图形API里访问Shader变量的方法, 总是默认使用字符串获取, 速度很慢. 当你想快速访问时, 请提前按需缓存字段<br>那么, Golang使用的也是这样的思路. 虽然暴力了一点, 但是能够让程序跑对, 性能优化的东西放在之后来做, 缓冲下就可以解决
<ul>
<li>在调用测试用例中, 毫无悬念的, 调用速度很慢<br>因此, 我们在平时使用反射时, 尽量偏向于反射变量缓冲存在下的变量赋值或者获取<br>而调用的需求尽量减少, 如果有goroutine存在的情况下, 则不必太多担心.</li></ul><img src ="http://www.cppblog.com/sunicdavy/aggbug/214152.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2016-08-12 15:26 <a href="http://www.cppblog.com/sunicdavy/archive/2016/08/12/214152.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Google Protobuf 3版本介绍</title><link>http://www.cppblog.com/sunicdavy/archive/2016/01/25/212739.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 25 Jan 2016 06:23:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2016/01/25/212739.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/212739.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2016/01/25/212739.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/212739.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/212739.html</trackback:ping><description><![CDATA[<p>本文编写时, Google 官方的 <a href="https://github.com/google/protobuf">protobuf</a> 版本是3.0.0beta</p> <p>下面介绍下proto3的一些细节变化</p> <h1>Proto3的语法变化</h1> <h2>语法标记</h2> <p>这个版本的protoc的protobuf编译器已经可以支持proto2语法和proto3的语法</p> <p>如果你的proto文件没有添加syntax说明的话, 用这个版本的编译器会报错, 提示你默认proto2支持, 请添加语法标记</p> <p>syntax = "proto2";</p> <p>&nbsp;</p> <h2>optional不需要了</h2> <p>只保留repeated标记数组类型, optional和required都被去掉了</p> <p>实际使用证明, required的设计确实是蛋疼, C++的调试版会弹出assert,release版和optional也没啥区别</p> <h2>map支持</h2> <p>map编写格式为</p><pre>map&lt;key_type, value_type&gt; map_field = N;</pre><pre>例如:</pre><pre>map&lt;string, Project&gt; projects = 3;</pre><pre>代码生成确认支持map, 这对于很多语言来说又可以偷懒了</pre>
<h2>字段default标记不能使用了</h2>
<p>位于proto2语法的字段number后的[default=XX]</p>
<p>这个东西不能用了, 理由是:</p>
<p>对于同一段序列化后的数据, 如果序列化端的default和反序列化端的default描述不一样会导致最终结果完全不一致</p>
<p>即: 同一个数据两个结果, 这是不可预测的结果, 因此干掉这个特性</p>
<p>不过本人觉得, 对于游戏来说, 这个功能本身可以压缩很多数据,虽然会有隐患</p>
<p>&nbsp;</p>
<h2>枚举默认值一定是0</h2>
<p>proto2里的默认值是枚举的第一个value对应的值, 不一定为0</p>
<p>proto3在你定义value时, 强制要求第一个值必须为0</p>
<p>这个修改为避免隐患还是有帮助的</p>
<h2>泛型描述支持</h2>
<p>any类型, 可以代表任何类型, 可以先读进来, 再进行解析, 没具体用, 步子跨大了怕扯到蛋</p>
<h2>支持json序列化</h2>
<p>这个极好, json再次被同化了</p>
<h2>增加了多种语言支持</h2>
<p>js, objc, ruby, C#等等</p>
<p>然而, C#版本的基础runtime库是用C# 6.0的语法写的,这对于Unity mono祖传2.0来说, 确实扯到蛋了,没法用</p>
<h2>Protobuf现在使用CMAKE做配置系统</h2>
<p>编译起来稍微麻烦, 还要下个被墙掉的cmake…</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h1>第三方库里对于proto3的变化</h1>
<p>Golang的官方protobuf支持: <a title="https://github.com/golang/protobuf" href="https://github.com/golang/protobuf">https://github.com/golang/protobuf</a></p>
<h2>生成代码中的结构体字段类型变化</h2>
<p>对于proto2的文件, 生成的go代码中的结构体依然使用类型指针作为默认存储, 兼容老的系统</p>
<p>对于proto3的文件, 生成的go代码中的结构体直接使用字段作为默认存储, 不再使用GetXXX来作为字段值访问, 赋值时也无需使用proto.类型() 函数进行指针类型字段值创建.</p>
<p>这个调整很是方便, 但丢失了optional判断功能, 对应C++里就是hasXXX的功能, 不过好歹这个逻辑现在用的不多了</p>
<p>这个修改大概也是配合json序列化来做的, go默认的json序列化时, 无法使用proto2生成的结构体的, 因为都是指针,无法赋值..</p>
<p>&nbsp;</p>
<h2>新版protoc-gen-go的插件会生成descriptor的压缩数据</h2>
<p>新插件会给每次生成的文件添加这样一段代码</p><pre><div class="csharpcode"><pre class="alt">var fileDescriptor0 = []<span class="kwrd">byte</span>{</pre><pre>    <span class="rem">// 220 bytes of a gzipped FileDescriptorProto</span></pre><pre class="alt">    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x8f, 0xcd, 0x4e, 0xc5, 0x20,</pre><pre>    0x10, 0x85, 0x53, 0xbd, 0x35, 0x32, 0xb7, 0xdd, 0x4c, 0x5c, 0xb0, 0x70, 0x71, 0xd3, 0xb8, 0x70,</pre><pre class="alt">    0x75, 0x17, 0xfa, 0x04, 0xc6, 0xd8, 0xb8, 0x50, 0x63, 0xa8, 0x2f, 0x80, 0xed, 0x44, 0x89, 0x28,</pre><pre>    0x04, 0xc6, 0xbf, 0x47, 0xf1, 0x6d, 0x95, 0x49, 0x8d, 0x4d, 0x5c, 0x01, 0xdf, 0x39, 0x7c, 0x30,</pre><pre class="alt">    0x00, 0x1c, 0x82, 0xdf, 0xc6, 0x14, 0x38, 0xe0, 0xaa, 0xec, 0xbb, 0x37, 0x68, 0x2e, 0x3e, 0x62,</pre><pre>    0x48, 0x7c, 0x49, 0x76, 0xa2, 0x84, 0x47, 0xd0, 0xde, 0x96, 0xf8, 0xee, 0x33, 0xd2, 0x8d, 0x7d,</pre><pre class="alt">    0x26, 0x5d, 0x6d, 0xaa, 0x63, 0x65, 0xda, 0xb8, 0x84, 0xd8, 0x41, 0x63, 0xc2, 0x7b, 0xef, 0xc8,</pre><pre>    0x4f, 0x52, 0xda, 0x91, 0x52, 0x93, 0x16, 0x0c, 0x0f, 0x41, 0x89, 0xa9, 0x77, 0x9e, 0xf4, 0xae,</pre><pre class="alt">    0x14, 0x54, 0xfc, 0x05, 0xdd, 0x57, 0x05, 0x4a, 0xba, 0xd7, 0xc4, 0x16, 0xb7, 0x80, 0x03, 0x27,</pre><pre>    0xf7, 0xf2, 0x70, 0x72, 0xe5, 0x32, 0x0f, 0xd1, 0x3b, 0xa6, 0x34, 0x5b, 0x31, 0xff, 0x4b, 0x70,</pre><pre class="alt">    0x03, 0x6b, 0x43, 0x91, 0x2c, 0x9f, 0x3f, 0xd2, 0xf8, 0x24, 0xf6, 0x7d, 0xb3, 0x4e, 0x7f, 0x08,</pre><pre>    0x0f, 0xa0, 0x3e, 0xf3, 0xce, 0x66, 0xbd, 0x12, 0x49, 0x6d, 0xcb, 0xa1, 0x4c, 0x37, 0xbf, 0xf3,</pre><pre class="alt">    0xb3, 0xbc, 0x8e, 0xac, 0x6b, 0xb9, 0xd9, 0xe6, 0x25, 0xbc, 0xdf, 0x93, 0x6f, 0x9e, 0x7e, 0x07,</pre><pre>    0x00, 0x00, 0xff, 0xff, 0x0c, 0x9f, 0x10, 0xa8, 0x2e, 0x01, 0x00, 0x00,</pre><pre class="alt">}</pre></div><style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style><br></pre>
<p>对于meta信息的提取还是很方便的</p>
<p>然而</p>
<p>对于多个文件的生成, 这样做非常的麻烦, 因为这个字段会重复导致编译错误</p>
<p>很多人在论坛里吐槽, 官方给出的解决方法是, 使用protoc一次性传入一个package下的所有的proto直接生成一个go</p>
<p>而不是现在的一个proto一个go</p>
<h2>生成代码会自动注册到全局, 并可以方便的查询</h2>
<p>以前这个代码需要自己来做, 现在官方提供了支持, 很是方便</p>
<p>然而, 为什么不支持遍历… 残念啊, 又要自己动手了</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/212739.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2016-01-25 14:23 <a href="http://www.cppblog.com/sunicdavy/archive/2016/01/25/212739.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于Protobuf的电子表格导出器tabtoy开源</title><link>http://www.cppblog.com/sunicdavy/archive/2016/01/25/212738.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 25 Jan 2016 06:00:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2016/01/25/212738.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/212738.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2016/01/25/212738.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/212738.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/212738.html</trackback:ping><description><![CDATA[<p>项目地址:</p> <p><a title="https://github.com/davyxu/tabtoy" href="https://github.com/davyxu/tabtoy">https://github.com/davyxu/tabtoy</a></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/212738.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2016-01-25 14:00 <a href="http://www.cppblog.com/sunicdavy/archive/2016/01/25/212738.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>服务器开发语言比较</title><link>http://www.cppblog.com/sunicdavy/archive/2016/01/05/212611.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 05 Jan 2016 08:51:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2016/01/05/212611.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/212611.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2016/01/05/212611.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/212611.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/212611.html</trackback:ping><description><![CDATA[<p>以下比较的基础都是基于一种编程语言+一定的第三方或者自己编写的网络库和底层进行的，Skynet稍微特殊，但总体比较合适放到比较中来</p> <h1>C#</h1> <p>开发效率：Windows下可以通过VisualStudio进行开发，其他平台可以使用MonoDevelop，非常方便</p> <p>运行效率：JIT的性能优化比较到位，能适应90%性能环境</p> <p>部署便捷性：可以通过交叉编译生成其他平台的可执行文件，通过mono运行可执行文件</p> <p>调试便捷性：VisualStudio和MonoDevelop调试均很方便， 还可远程调试</p> <p>上手度：对C系语言熟悉的几天就可上手</p> <p>热更新：可以通过DLL方式进行</p> <p>Web对接：可做，代码比较啰嗦</p> <p>崩溃处理：可通过try catch捕获错误</p> <p>网络库编写难度：一般，需注意gc问题</p> <p>第三方网络库及框架数量：一般</p> <p>&nbsp;</p> <h1>Golang</h1> <p>开发效率：高</p> <p>运行效率：并发上非常有优势，对CPU利用率比较高，原生运行无虚拟机</p> <p>部署便捷性：一次编译到处运行，无任何运行库依赖</p> <p>调试便捷性：实际操作中，单线程挂接调试器可行， 但变量显示不正确，开发期基本采用日志方式进行查错</p> <p>上手度：语言简单，特性少， 新手1周能贡献代码</p> <p>热更新：无法进行热更新，语言无法编译为DLL，也不支持DLL加载（linux平台的.so加载忽略不计）</p> <p>Web对接：非常方便， 代码精简</p> <p>崩溃处理：崩溃后以命令行方式打印出栈，程序内可以捕获任何崩溃错误并继续运行</p> <p>网络库编写难度：简单，比C socket更简单</p> <p>第三方网络库及框架数量：偏少</p> <p>&nbsp;</p> <h1>Skynet(lua+C)</h1> <p>开发效率：基于动态语言的开发初次写比较快，后期维护和重构会耗费一定的时间在查错上</p> <p>运行效率：基于lua jit的运行效率还是能接受的</p> <p>部署便捷性：方便， 只有底层修改需要重新编译， 大部分时间只用更新lua文件</p> <p>调试便捷性：不是很方便，基于日志方式进行查错</p> <p>上手度：lua语言特性有部分和C系语言有一定差异，基于Actor模型的思想学习，适应需要耗费一定的时间</p> <p>热更新：类似于Erlang，可精确到函数级的热更新</p> <p>Web对接：有一些http支持，通过社区慢慢进行完善</p> <p>崩溃处理：lua天生可以捕获错误</p> <p>网络库编写难度：自带，无需编写</p> <p>第三方网络库及框架数量：通过社区慢慢完善</p> <p>&nbsp;</p> <h1>C++</h1> <p>开发效率：编译慢，文件多，通用库少</p> <p>运行效率：native速度标杆</p> <p>部署便捷性：编写各类的make门槛较高</p> <p>调试便捷性：可通过VisualStudio进行Windows平台调试</p> <p>上手度：2~3年经验的熟手仍然会写出崩溃和泄露代码</p> <p>热更新：可通过DLL进行</p> <p>Web对接：代码啰嗦，第三方库少</p> <p>崩溃处理：Windows下可使用SEH捕获段异常，其他平台只能通过崩溃后进行coredump分析，容错非常差</p> <p>网络库编写难度：基于asio编写较为简单，但总体看来难度不低</p> <p>第三方网络库及框架数量：较多</p> <p>&nbsp;</p> <p>以下是得分</p> <p></td></tr><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/cce8cda86825_E2DC/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/cce8cda86825_E2DC/image_thumb.png" width="326" height="268"></a> <p>&nbsp; <p>从发文时的项目对这些语言使用率来说，Java，Erlang，C++编写的服务器较多，Golang，JavaScript，C#是第二梯队，Skynet由于上手不是很容易，所以仅有两位数的团队在使用，但总体表现还是比较出色的 <p>对于老团队， C++的服务器工具链和框架已经相对成熟， 完全没必要更换新语言， 只是在对接sdk感觉困难时，可以尝试Golang这些对web有优势的语言进行混合语言开发 <p>对于新团队，开发效率，上手度和部署效率是优先选择的，C#，Golang，JavaScript这些新兴语言会让你事半功倍 <p>对于大规模无需选服的服务器， Skynet的actor模型对扩展会比较容易 <p>对于大公司，好项目，上线后需要通过热更新进行bug修补的，C#，C++，Erlang会是首选 <p>&nbsp; <p>但总的一点， 还是根据团队熟悉度来选择语言，贸然的使用新语言的风险也是很大的 <img src ="http://www.cppblog.com/sunicdavy/aggbug/212611.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2016-01-05 16:51 <a href="http://www.cppblog.com/sunicdavy/archive/2016/01/05/212611.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开源Golang游戏服务器框架cellnet</title><link>http://www.cppblog.com/sunicdavy/archive/2015/10/16/212026.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 16 Oct 2015 03:44:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2015/10/16/212026.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/212026.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2015/10/16/212026.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/212026.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/212026.html</trackback:ping><description><![CDATA[<p>简单,方便,高效的Go语言的游戏服务器框架</p> <div class="csharpcode"><pre class="alt">func server() {</pre><pre>&nbsp;</pre><pre class="alt">    pipe := cellnet.NewEventPipe()</pre><pre>&nbsp;</pre><pre class="alt">    evq := socket.NewAcceptor(pipe).Start(<span class="str">"127.0.0.1:7234"</span>)</pre><pre>&nbsp;</pre><pre class="alt">    socket.RegisterSessionMessage(evq, coredef.TestEchoACK{}, func(content <span class="kwrd">interface</span>{}, ses cellnet.Session) {</pre><pre>        msg := content.(*coredef.TestEchoACK)</pre><pre class="alt">&nbsp;</pre><pre>        log.Println(<span class="str">"server recv:"</span>, msg.String())</pre><pre class="alt">&nbsp;</pre><pre>        ses.Send(&amp;coredef.TestEchoACK{</pre><pre class="alt">            Content: proto.String(msg.String()),</pre><pre>        })</pre><pre class="alt">&nbsp;</pre><pre>    })</pre><pre class="alt">&nbsp;</pre><pre>    pipe.Start()</pre><pre class="alt">&nbsp;</pre><pre>}</pre><pre class="alt">&nbsp;</pre><pre>func client() {</pre><pre class="alt">&nbsp;</pre><pre>    pipe := cellnet.NewEventPipe()</pre><pre class="alt">&nbsp;</pre><pre>    evq := socket.NewConnector(pipe).Start(<span class="str">"127.0.0.1:7234"</span>)</pre><pre class="alt">&nbsp;</pre><pre>    socket.RegisterSessionMessage(evq, coredef.TestEchoACK{}, func(content <span class="kwrd">interface</span>{}, ses cellnet.Session) {</pre><pre class="alt">        msg := content.(*coredef.TestEchoACK)</pre><pre>&nbsp;</pre><pre class="alt">        log.Println(<span class="str">"client recv:"</span>, msg.String())</pre><pre>&nbsp;</pre><pre class="alt">    })</pre><pre>&nbsp;</pre><pre class="alt">    socket.RegisterSessionMessage(evq, coredef.SessionConnected{}, func(content <span class="kwrd">interface</span>{}, ses cellnet.Session) {</pre><pre>&nbsp;</pre><pre class="alt">        ses.Send(&amp;coredef.TestEchoACK{</pre><pre>            Content: proto.String(<span class="str">"hello"</span>),</pre><pre class="alt">        })</pre><pre>&nbsp;</pre><pre class="alt">    })</pre><pre>&nbsp;</pre><pre class="alt">    pipe.Start()</pre><pre>}</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>&nbsp;</p>
<p>项目地址: <a title="https://github.com/davyxu/cellnet" href="https://github.com/davyxu/cellnet">https://github.com/davyxu/cellnet</a></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/212026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2015-10-16 11:44 <a href="http://www.cppblog.com/sunicdavy/archive/2015/10/16/212026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Golang, Lua, C#闭包变量捕获差异</title><link>http://www.cppblog.com/sunicdavy/archive/2015/09/23/211895.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 23 Sep 2015 10:31:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2015/09/23/211895.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/211895.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2015/09/23/211895.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/211895.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/211895.html</trackback:ping><description><![CDATA[<p>看C#例子</p> <div class="csharpcode"><pre class="alt">            Action[] a = <span class="kwrd">new</span> Action[3];</pre><pre>&nbsp;</pre><pre class="alt">            <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; 3; i++)</pre><pre>            {</pre><pre class="alt">                a[i] = ( ) =&gt; { Console.WriteLine(i); };</pre><pre>            }</pre><pre class="alt">&nbsp;</pre><pre>            <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; 3; i++){</pre><pre class="alt">                a[i]();</pre><pre>            }</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>C#打印结果为3 3 3</p>
<p>&nbsp;</p>
<p>Golang的例子</p>
<div class="csharpcode"><pre class="alt">    a := make([]func(), 3 )</pre><pre>    </pre><pre class="alt">    <span class="kwrd">for</span> i := 0; i &lt; 3; i++ {</pre><pre>        </pre><pre class="alt">        a[i]= func( ){</pre><pre>            </pre><pre class="alt">            fmt.Println(i)</pre><pre>            </pre><pre class="alt">        }    </pre><pre>    </pre><pre class="alt">    }</pre><pre>    </pre><pre class="alt">    <span class="kwrd">for</span> _, s := range a {</pre><pre>        s()</pre><pre class="alt">    }</pre></div>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>Golang打印结果为3 3 3</p>
<p>&nbsp;</p>
<p>最后是Lua的例子</p>
<div class="csharpcode"><pre class="alt">a = {}</pre><pre>&nbsp;</pre><pre class="alt"><span class="kwrd">for</span> i = 1, 3 <span class="kwrd">do</span></pre><pre>&nbsp;</pre><pre class="alt">    table.insert( a, function()</pre><pre>        print(i)</pre><pre class="alt">    end</pre><pre>    )</pre><pre class="alt">&nbsp;</pre><pre>end</pre><pre class="alt">&nbsp;</pre><pre>&nbsp;</pre><pre class="alt"><span class="kwrd">for</span> _, v <span class="kwrd">in</span> ipairs(a) <span class="kwrd">do</span></pre><pre>    v()</pre><pre class="alt">end</pre></div>
<p>Lua打印结果为1 2 3</p>
<p>&nbsp;</p>
<p>差异在于, C#和Golang将变量捕获到闭包内时, 均使用引用方式, 即当最后开始调用使用变量时, 由于变量已经结束循环, 所以是最终值</p>
<p>但是Lua捕获方式是值捕获, 因此比较容易理解, 是多少就是多少</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/211895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2015-09-23 18:31 <a href="http://www.cppblog.com/sunicdavy/archive/2015/09/23/211895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对golang服务器开发模式的一些思考</title><link>http://www.cppblog.com/sunicdavy/archive/2015/09/09/211784.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 09 Sep 2015 11:06:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2015/09/09/211784.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/211784.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2015/09/09/211784.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/211784.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/211784.html</trackback:ping><description><![CDATA[<h1>多线程+同步阻塞模型</h1> <p>在我们的游戏项目中使用的golang服务器开发方式如下</p> <p>1.多线程逻辑</p> <p>2.同步阻塞. 也就是说, 每个人一个线程(goroutine), io线程=逻辑线程</p> <p>这种方式的优点:</p> <p>1. 同步阻塞方式与人的思维方式类同</p> <p>2. 逻辑处理性能有一定提升</p> <p>在大规模使用这种模式编写逻辑后, 我们发现了这种模式只有1个缺点: <strong>编写者需要处理多线程关系</strong></p> <p>但这本身确实直接致命的, 回想C++时代, 多线程处理时, 调试重现的困难… 脑补景象太惨不敢直视</p> <h1>单线程+异步多进程模型</h1> <p>在C++时代, 我曾经编写过一套asio的C++服务器框架. 采用io多线程, 逻辑单线程, 依赖着C++高性能的优势, 让开发便捷简单且无需关心线程问题.</p> <p>那么到了golang时代, 为什么不能试下单线程异步多进程方式来编写逻辑?</p> <p>与多线程同步阻塞对比后, 我们发现, 两者优缺点互补. 那这就回到了领域选型问题了. 对于游戏服务器需要的上手简单, 开发便捷, 压力降低(非MMO)这些特点来说, 单线程异步多进程再合适不过了</p> <p>那么, 我们在用golang编写单线程异步多进程服务器应该注意哪些点呢?</p> <p>1. socket处理完全封装, 只通过channel抛出到逻辑线程排队处理</p> <p>2. 数据库, rpc及其他io处理, 一律改为异步回调模式, 不使用同步接口</p> <p>3. 玩家存盘提交数据可以考虑复制并提交到存盘线程方式, 提高性能. </p> <p>4. 采用多进程架构, 比如设网关进程, 把io压力分散到进程中</p> <p>5. 逻辑编写中, 不允许使用go开线程及channel, 有需要提高性能部分需要单独编写</p> <p>&nbsp;</p> <h1>Actor模型的痛</h1> <p>cellnet在开发时本来考虑使用actor模型来进一步简化多线程逻辑的麻烦, 经历了一段时间的原型开发后, 发现了一些问题, 列举如下:</p> <p>1. golang的强类型不适合actor模型这种经常需要动态生成各类消息的模型, 但skynet(C+lua)/erlang就有天生优势</p> <p>2. actor模型本身不是万能的, 不能解决所有需求, 特别是游戏</p> <p>3. actor模型理解到应用有一定的难度. 本身还需要搭建框架, 上手复杂</p> <p>总之, 看过一些erlang及skynet的用例, 没有应用的很纯正且成熟的成功actor模型案例, 从传统socket服务器框架跨越到actor模型会扯到蛋, 因此, 后期cellnet会考虑回归到成熟的socket服务器框架. 把架构做到简单上手, 高扩展上.</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/211784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2015-09-09 19:06 <a href="http://www.cppblog.com/sunicdavy/archive/2015/09/09/211784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大服务器架构讨论</title><link>http://www.cppblog.com/sunicdavy/archive/2015/07/21/211321.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 21 Jul 2015 02:30:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2015/07/21/211321.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/211321.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2015/07/21/211321.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/211321.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/211321.html</trackback:ping><description><![CDATA[<p>最近参加了一个大服务器架构讨论活动, 记录下心得 <h1>概述</h1> <p>游戏客户端采用Cocos2dx-Lua的纯Lua编写逻辑, 服务器采用Golang作为开发语言 <p>游戏类型类似于COC,因此无需选服. 需要使用大服务器架构进行处理 <h1><b>数据库</b></h1> <p>采用Mongodb做持久存储, redis做跨服通信数据交换 <p>使用UCloud的云技术, 省去了烦人的运维工作 <h1><b>通信及协议</b></h1> <p>客户端和服务器通讯使用HTTP短连接, 基于json的数据封包协议 <p>服务器间大量使用Golang自带的json+rpc进行通信 <h1><b>服务器类型</b></h1> <p>服务器类型大致分为逻辑服务器,战斗服务器, 中心服务器 <h2><b>逻辑服务器</b></h2> <p>逻辑服务器负责日常逻辑及公共逻辑处理(好友, 公会) <p>1个逻辑服务器对应一个区, n个区均使用Ucloud云Mongodb进行数据存储 <h2><b>战斗服务器</b></h2> <p>战斗服务器是一个集群, 集群会返回一个负载最低的服务器返回使用 <p>战斗服务器通过cgo技术与客户端C++/lua的战斗逻辑进行逻辑复用, 在此技术上进行 <p>战斗逻辑的校验 <h2><b>中心服务器</b></h2> <p>客户端登陆前, 在中心服务器这里获得可登陆的逻辑服务器地址, 同时做一个负载均衡 <p>短连接 <h1><b>评价</b></h1> <p>由于操作系统的技术趋于稳定, 同时, 手游的弱交互型导致的游戏架构趋于简单. 因此网络负载不再是游戏服务器技术的瓶颈. 从经验看来, 游戏服务器技术, 更重要的是还是看数据库的选型及处理方式.&nbsp; <p>虽然Mongodb的性能上不如内存数据库. 但是从存储安全性上要比个人搭建的内存数据库简单, 安全 <p>外加上云技术的引用, 性能的瓶颈和运维的技术复杂度迎刃而解 <p>Redis用于跨服数据交互那是再好不过的数据中介了, 保证速度和稳定性, 绝对不是造轮子能比拟的 <p>短连接在手游上处理起来比长连接简单一些, 无需做断线重连. 服务器的底层也是由Golang的框架库保证质量的. 因此负载毫无问题. 服务器对内及对外均使用json进行数据交换, 简化了协议处理. 也方便了调试 <p>json rpc的性能损耗对于整个逻辑的处理来说均可以忽略不计</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/211321.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2015-07-21 10:30 <a href="http://www.cppblog.com/sunicdavy/archive/2015/07/21/211321.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的Golang全接触</title><link>http://www.cppblog.com/sunicdavy/archive/2015/06/04/210823.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 04 Jun 2015 09:19:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2015/06/04/210823.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/210823.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2015/06/04/210823.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/210823.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/210823.html</trackback:ping><description><![CDATA[<p>满打满算, 从好友推荐Golang至发文时, 使用Golang已经有1年多了. 这种时间对于C/C++ Java这些老者来说, 简直是菜鸟级别的经验</p> <p>但作为新生代语言的特点就是实战. Golang这一年里, 已经为项目提供了稳定的服务器和强大的扩展能力, 与客户端的Unity3D里的C#一样, 都是强大, 极致开发效率代表的优秀开发语言.</p> <h2>用途篇</h2> <p>Golang到底拿来做啥? 我需要么?</p> <p> 高效(性能,开发)的服务器语言. 包括Web, 游戏, App</p> <p>编写桌面级UI暂不是很适合</p> <p>我需要把现在的C++, Python, Erlang等服务器改成Golang么?</p> <p>性能有瓶颈, 开发效率低, 有钱有时间的话, 完全可以</p> <p>&nbsp;</p> <h2>评价篇</h2> <p>听过太多的人对Golang的评价, 大概分为这么几类: </p> <h3>C/C++性能党</h3> <p>此类党员对任何事物都追求极致的 性能. 还好Golang是直接生成native code, 否则会被批的体无完肤. 但是由于Golang底层为并发和开发效率而做出的一些系统, 类似于GC, 调度器和分配器等, 会在语言层上损失很多性能. 因此C/C++党还是有理由批Golang性能低下</p> <h3>Erlang并发党</h3> <p>作为电信级元老, Erlang的模型和架构当之无愧, OTP扩展性超级强. 完美的Actor模型也让逻辑编写比OO更加直观</p> <p>CSP与Actor区别仅仅只是在channel的归属范围而已, 但这点细微差别却对两种语言的开发变的迥然不同</p> <p>Golang在并发模型上选择了CSP, 就是考虑把架构的设计留给使用者. 像C#一样建立一个类库的世界, 而不是MFC一样的框架世界. 让开发更自由</p> <p>Erlang的Actor也没错. 让开发更直观, 让崩溃提前来到, 尽快处理</p> <h3>Rust党</h3> <p>Rust在发文时已经发布了1.0. 这让R粉兴奋的穿梭于各大技术论坛和讨论群</p> <p>但Rust的理念在我看来有点偏执了, 一定要把各种错误在编译期暴露出来, 所以造出了很多不需要的类型和概念, 连语言都比C语言更符号话</p> <p>大白话说来, 有点编程经验的人看到JavaScript完全看得懂, 但看Rust却像天书</p> <p>对比同时期的TypeScript, Dart, Swift. Rust就是有点那么独辟蹊径</p> <p>该党党员经常性的用各种特性对比Golang, 追求单特性的优秀. </p> <p>但其实, Golang本身是一门完整哲学. 很多语言特性互相之间有关联. 有设计不当的地方, 当然更多的是完整体系. 不求和其他语言比</p> <p>只追求解决问题的速度</p> <h3>自定义党</h3> <p>云风看过Golang后, 因为该语言本身就是强化版的C, 因此颇受云风喜欢. 但在一堆评价后, 云风还是果断选择了C+lua的组合写出的Skynet</p> <p>虽然不知道原因, 但我猜的话, 毕竟是对语言本身的可控性还不那么看好</p> <p>同时, 我们发现Skynet使用的是Actor模型, 也发现大神级的程序员就是有先见. </p> <p><font style="background-color: #ffffff" color="#ffffff">转载请注明: 战魂小筑</font><a title="http://www.cppblog.com/sunicdavy" href="http://www.cppblog.com/sunicdavy"><font style="background-color: #ffffff" color="#ffffff">http://www.cppblog.com/sunicdavy</font></a></p> <h2>感触篇</h2> <p><strong>设计</strong></p> <p>踏入Golang, 就不要尝试设计模式</p> <p>传统的OO在这里是非法的, 尝试模拟只是一种搞笑</p> <p>把OO在Golang里换成复合+接口</p> <p>对实现者来说, 把各种结构都复合起来, 对外暴露出一个或多个接口, 接口就好像使用者在实现模型上打出的很多洞</p> <p>别怕全局函数, 包(Package)可以控制全局函数使用范围. </p> <p>没必要什么都用interface对外封装, struct也是一种良好的封装方法</p> <p>Golang无继承, 因此无需类派生图. 没有派生这种点对点的依赖, 因此不会在大量类关系到来时, 形成繁杂不可变化的树形结构</p> <p>&nbsp;</p> <p><strong>容器</strong></p> <p>用了很长时间map, 才发现Golang把map内建为语言特性时, 已经去掉了外置型map的api特性. 一切的访问和获取都是按照语言特性来做的, 原子化</p> <p>数组可以理解为底层对象, 你平时用的都是切片, 不是数组, 切片就是指针, 指向数组. 切片是轻量的, 即便值拷贝也是低损耗的</p> <p>&nbsp;</p> <p><strong>内存</strong></p> <p>Golang在实际运行中, 你会发现内存可能会疯涨. 但跑上一段时间后, 就保持稳定. 这和Golang的内存分配, 垃圾回收有一定的关系</p> <p>现代的编程语言的内存管理不会很粗暴的直接从OS那边分配很多内存. 而是按需的不断分配成块的内存. </p> <p>对于非海量级应用, Golang本身的内存模型完全可以撑得下来. 无需像C++一样, 每个工程必做内存池和线程池</p> <p><strong>Channel</strong></p> <p>Channel和锁谁轻量? 一句话告诉你: Channel本身用锁实现的. 因此在迫不得已时, 还是尽量减少使用Channel, 但Channel属于语言层支持, 适度使用, 可以改善代码可读写</p> <p><font style="background-color: #ffffff" color="#ffffff">转载请注明: 战魂小筑</font><a title="http://www.cppblog.com/sunicdavy" href="http://www.cppblog.com/sunicdavy"><font style="background-color: #ffffff" color="#ffffff">http://www.cppblog.com/sunicdavy</font></a></p> <p><strong>错误</strong></p> <p>觉得Golang不停的处理err? 那是因为平时在其他语言根本没处理过错误, 要不然就是根部一次性try过所有的异常, 这是一种危险的行为</p> <p>panic可以被捕获, 因此编写服务器时, 可以做到不挂</p> <p>&nbsp;</p> <p><strong>危险的interface{}</strong></p> <p>这东西就跟C/C++里的void*一样的危险, nil被interface{}包裹后不会等于nil相等, 但print出来确实是nil</p> <p>模板估计可以解决容器内带interface{}的问题. 但新东西引入, 估计又会让现在的哲学一些凌乱</p> <p>&nbsp;</p> <p><font style="background-color: #ffffff" color="#ffffff">转载请注明: 战魂小筑</font><a title="http://www.cppblog.com/sunicdavy" href="http://www.cppblog.com/sunicdavy"><font style="background-color: #ffffff" color="#ffffff">http://www.cppblog.com/sunicdavy</font></a></p> <p>&nbsp;</p> <h2><strong>初学Tips</strong></h2> <p>语言学习按照官网的教学走, 跑完基本就会了</p> <p>下载一个LiteIDE, 配合Golang的Runtime,基本开环境就有了</p> <p>Golang的类库设计方式和C#/C++都不同, 如果有Python经验的会感觉毫无违和感</p> <p>有一万个理由造轮子都请住手, 类库里有你要的东西</p> <p>写大工程请搜索: <a name="688">Golang项目目录结构组织</a></p> <p>Golang语言本身本人没有发现bug, 即便有也早就被大神们捉住了. 唯一的一个感觉貌似bug的, 经常是结构体成员首字母小写, 但是json又无法序列化出来…</p> <p> <p><a name="688">慎用cgo. 官方已经声明未来对cgo不提供完整兼容性. 任何一门语言在早期都需要对C做出支持, 但后期完善后的不兼容都是常态</a></p> <p>&nbsp;</p> <p><font style="background-color: #ffffff" color="#ffffff">转载请注明: 战魂小筑</font><a title="http://www.cppblog.com/sunicdavy" href="http://www.cppblog.com/sunicdavy"><font style="background-color: #ffffff" color="#ffffff">http://www.cppblog.com/sunicdavy</font></a></p> <p>&nbsp;</p> <p><a name="688">&nbsp;</p></a><img src ="http://www.cppblog.com/sunicdavy/aggbug/210823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2015-06-04 17:19 <a href="http://www.cppblog.com/sunicdavy/archive/2015/06/04/210823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>golang的time.Format的坑</title><link>http://www.cppblog.com/sunicdavy/archive/2015/03/26/210173.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 26 Mar 2015 09:23:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2015/03/26/210173.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/210173.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2015/03/26/210173.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/210173.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/210173.html</trackback:ping><description><![CDATA[<p>golang的time.Format设计的和其他语言都不一样, 其他语言总是使用一些格式化字符进行标示, 而golang呢, 查了网上一些坑例子 自己查了下golang的源码, 发现以下代码<pre><code>// String returns the time formatted using the format string
//  "2006-01-02 15:04:05.999999999 -0700 MST"
func (t Time) String() string {
    return t.Format("2006-01-02 15:04:05.999999999 -0700 MST")
}
</code></pre>
<p>尝试将2006-01-02 15:04:05写入到自己的例子中<pre><code>func nowTime() string {
    return time.Now().Format("2006-01-02 15:04:05")
}
</code></pre>
<p>结果返回正确. 询问了下, 据说这个日期是golang诞生的日子… 咋那么自恋呢…
<img src ="http://www.cppblog.com/sunicdavy/aggbug/210173.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2015-03-26 17:23 <a href="http://www.cppblog.com/sunicdavy/archive/2015/03/26/210173.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>