﻿<?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++博客-战魂小筑-随笔分类-工具使用及设计</title><link>http://www.cppblog.com/sunicdavy/category/12950.html</link><description>讨论群:309800774 知乎关注:http://zhihu.com/people/sunicdavy 开源项目:https://github.com/davyxu</description><language>zh-cn</language><lastBuildDate>Tue, 19 Dec 2017 16:36:53 GMT</lastBuildDate><pubDate>Tue, 19 Dec 2017 16:36:53 GMT</pubDate><ttl>60</ttl><item><title>嵌套git库的管理</title><link>http://www.cppblog.com/sunicdavy/archive/2017/12/19/215432.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 19 Dec 2017 14:04:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2017/12/19/215432.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/215432.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2017/12/19/215432.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/215432.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/215432.html</trackback:ping><description><![CDATA[<div yne-bulb-block="heading" yne-bulb-level="1" id="8683-1513690294872" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 28px; font-weight: bold;">嵌套git库的管理</span></div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">使用git作为源代码管理时，经常需要在一个git代码库中从外网获取新的git库，也就是在git库下嵌套另外一个git库。而同时维护两个git库的过程就变的非常复杂。</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div><div yne-bulb-block="heading" yne-bulb-level="2" id="9569-1513690617117" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 20px; font-weight: bold;">submodule的弊端</span></div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">常见的做法是使用git 提供的submodule功能。但submodule的管理嵌套git库的结果往往不是我们期望的结果。假设有一个git库叫project，在project的某个子目录下还包含一个叫3rd的目录，是另外一个git库。</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">D:.</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">&#9492;&#9472;project</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">    &#9492;&#9472;3rd</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">            mytext.txt</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">假设甲和乙都取了project的代码，由于时间差异，甲通过submodule取到V1版，而乙取到了V2版本。甲乙同时在不同的3rd库下进行开发，势必会造成不同的运行结果。也许你认为可以在获取submodule时指定版本，但这个获取过程很难控制。</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">一般说来，第三方库应由主程序进行更新及维护，一般情况下，项目没有特殊需求时，不会随便更新第三方库到最新版本，因此submodule更新嵌套的git库并不是理想的解决方案。</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div><div yne-bulb-block="heading" yne-bulb-level="2" id="3018-1513690681993" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 20px; font-weight: bold;">嵌套git库的修改可见性</span></div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">前面的例子中，project git库下的3rd的git库中如果有文件发生修改，此时在project目录下，使用sourceTree等git管理工具无法识别3rd下的文件修改。</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">也就是说，无法将3rd下的修改提交到project的git库中。</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;"></div><div yne-bulb-block="heading" yne-bulb-level="2" id="2131-1513690883989" style="white-space: pre-wrap; line-height: 1.75;"><span style="font-size: 20px; font-weight: bold;">终极解决方案</span></div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75;">此时，<span style="font-weight: bold;">将3rd目录下的.git目录暂时移出project和3rd目录</span>，此时，在project目录用sourceTree查看时，将可以看到3rd下的文件修改，提交修改到project库中。再将刚移出去的3rd的.git目录移回3rd目录下，在3rd目录下使用git status，将可看到3rd目录的修改，提交时，会将修改提交到3rd目录。</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;"></div><img src ="http://www.cppblog.com/sunicdavy/aggbug/215432.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-12-19 22:04 <a href="http://www.cppblog.com/sunicdavy/archive/2017/12/19/215432.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Windows下运行Linux Shell</title><link>http://www.cppblog.com/sunicdavy/archive/2017/11/27/215373.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 27 Nov 2017 07:15:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2017/11/27/215373.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/215373.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2017/11/27/215373.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/215373.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/215373.html</trackback:ping><description><![CDATA[<p data-source-line="2" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;"></p><h1></h1><p data-source-line="2" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;">越来越多的人选择用Mac或者Linux环境进行跨平台项目开发。但是仍然有大部分人习惯于在Windows环境下进行开发，毕竟Windows在各方面使用还是较为方便，特别像文件版本管理（Git，SVN等）</p><p data-source-line="4" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;">在跨平台下开发游戏或软件，就需要有一套方便的自动化工具。Windows下需要使用批处理，虽然有PowerShell加持，但这东西学了也不靠谱，只有一个平台能用。大家还是习惯Linux Shell。连Mac平台都可以用Shell，Windows上要做自动化脚本就显得非常尴尬。</p><p data-source-line="6" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;">我曾经在项目中使用go编写了一套将配置转为批处理和Linux Shell的工具。使用过程较为复杂，但是能跨平台进行表格导出和协议编译等工作。</p><p data-source-line="8" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;">但是，这个工具还是需要对不同的平台编写多套模板进行代码生成，非常繁琐。如果有一套跨平台的Shell，编写一次就可以跨平台运行那该多好。</p><p data-source-line="10" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;">查阅资料后，一共有几个方案：</p><ol data-source-line="11" style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;"><li style="box-sizing: border-box;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">使用Python作为自动化工具 这个方案其实就是使用python把批处理和Shell干的事情用代码来解决。但前提是要重新学习Python，也需要一部分熟悉简单的Python语法，人为学习成本较高，也比较费事。</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></li><li style="box-sizing: border-box; margin-top: 0.25em;"><p style="box-sizing: border-box; margin-top: 16px; margin-bottom: 16px;">自己编写Linux Shell的解释器 这个就更难了，要做到100%兼容，基本不可能。</p></li></ol><ol start="4" data-source-line="21" style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;"><li style="box-sizing: border-box;">使用Cygwin和Mingw 需要一个微型运行时进行Linux Shell的解释，msys大概是18M左右，可行性较高。</li></ol><p data-source-line="24" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;">在研究Cygwin和Mingw如何整合的过程中，我误操作点击了一个sh后缀的Linux Shell，这是我希望让Mingw运行的Shell。结果呢，sh后缀的文件居然能在Windows下运行。我马上编写了一系列的例子，发现几乎完全兼容常用的Shell指令。 经过研究，我发现Windows下能运行sh文件是由Git自带的msys2提供的。MSYS2 （Minimal SYStem 2，&nbsp;<a href="http://www.msys2.org/%EF%BC%89" style="box-sizing: border-box; background-color: transparent; color: #0366d6; text-decoration-line: none;">http://www.msys2.org/）</a>&nbsp;是一个MSYS的独立改写版本，主要用于 shell 命令行开发环境。同时它也是一个在Cygwin （POSIX 兼容性层） 和 MinGW-w64（从"MinGW-生成"）基础上产生的，追求更好的互操作性的 Windows 软件。</p><p data-source-line="27" style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff;">那就是说，<span style="box-sizing: border-box; font-weight: 600;">只要安装了Git（<a href="https://git-scm.com/%EF%BC%89%EF%BC%8C%E9%82%A3%E4%B9%88%E5%B0%B1%E5%8F%AF%E4%BB%A5%E5%9C%A8Windows%E4%B8%8B%E7%9B%B4%E6%8E%A5%E8%BF%90%E8%A1%8CLinux" style="box-sizing: border-box; background-color: transparent; color: #0366d6; text-decoration-line: none;">https://git-scm.com/），</a></span><strong><span style="font-family: verdana, &quot;courier new&quot;;">那么就可以在Windows下直接运行Linux Shell</span><span style="box-sizing: border-box;">，只需要将文件后缀命名为sh即可</span></strong>。</p><p data-source-line="29" style="box-sizing: border-box; margin-top: 0px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff; margin-bottom: 0px !important;">问过周边友人是否知道这一功能，都说知道，只是没有广播而已，害我研究很久&#8230;&#8230;</p><p data-source-line="29" style="box-sizing: border-box; margin-top: 0px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff; margin-bottom: 0px !important;"></p><p data-source-line="29" style="box-sizing: border-box; margin-top: 0px; color: #24292e; font-family: -apple-system, BlinkMacSystemFont, 微软雅黑, &quot;PingFang SC&quot;, Helvetica, Tahoma, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, SimSun, 宋体, Heiti, 黑体, sans-serif; background-color: #ffffff; margin-bottom: 0px !important;"></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/215373.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-11-27 15:15 <a href="http://www.cppblog.com/sunicdavy/archive/2017/11/27/215373.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/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>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>git服务器简易搭建法</title><link>http://www.cppblog.com/sunicdavy/archive/2015/06/10/210870.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 10 Jun 2015 06:53:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2015/06/10/210870.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/210870.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2015/06/10/210870.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/210870.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/210870.html</trackback:ping><description><![CDATA[<p>受尽svn各种折磨的小伙伴都听说过git. 但是网上一搜索, 本来打算跟svn一样. 下一个服务器, 装下就可以开始用了.</p> <p>没想到啊, 没想到. 居然需要Linux天赋点…</p> <p>好吧, 拜鸟哥门下把Linux上手了吧, 刚开始搭git, 靠. 又需要公钥和各种辅助软件.</p> <p>伤不起啊</p> <p>很多小伙伴们, 自此继续沉默的继续使用svn</p> <p>我们没有放弃, 我们找到了简(shan)易(zhai)搭建法</p> <p>&nbsp;</p> <h2>先看疗效:</h2> <p>1. 无需公钥</p> <p>2. 只需要几个最常用的Linux命令就可以搭建</p> <p>&nbsp;</p> <h2>看步骤</h2> <p>1. 准备Linux服务器, 安装好git(一般都是默认装好的)</p> <p>2. 命令行操作</p> <p>useradd git&nbsp;&nbsp; #创建一个git账号</p> <p>passwd git&nbsp;&nbsp;&nbsp; #设置git账号的密码</p> <p>su – git&nbsp;&nbsp;&nbsp; #切换到git账号</p> <p>cd ~&nbsp; #转到用户目录</p> <p>mkdir 项目名称.git&nbsp;&nbsp; #建立项目git文件夹</p> <p>cd 项目名称.git </p> <p>git –-bare –share init&nbsp;&nbsp; #初始化git库</p> <p>&nbsp;</p> <p>3. 马上拿起你的git客户端( 乌龟, SourceTree均可)输入这样格式的地址<a href="mailto:git@ip:/path/to/project.git">git@ip:/path/to/project.git</a></p> <p>例如: <a href="mailto:git@192.168.1.2:/home/git/YourProject.git">git@192.168.1.2:/home/git/YourProject.git</a></p> <p>git pull时, 需要输入密码, 就输入上面创建好的git账号的密码就可以</p> <p>开始使用吧!</p> <p>&nbsp;</p> <h2>Tips</h2> <p>这种方法搭建的git服务器仅限于小团队和对贡献代码不敏感的项目而生</p> <p>git本身的公钥是为了防止别人伪造用户名进行虚假提交. 但这个方法绕开了这点</p> <p>想开新的git库时, 切记使用git账号去重复以上步骤, 若使用root级别账号创建的文件夹使用客户端时会遇到权限不足的提示</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/210870.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-10 14:53 <a href="http://www.cppblog.com/sunicdavy/archive/2015/06/10/210870.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用SVN处理多人共享修改文件</title><link>http://www.cppblog.com/sunicdavy/archive/2015/03/06/209943.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 06 Mar 2015 08:27:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2015/03/06/209943.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/209943.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2015/03/06/209943.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/209943.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/209943.html</trackback:ping><description><![CDATA[<p>SVN的工作流是checkout-&gt;modify-&gt;update-&gt;merge-&gt;commit, 如果多人修改同一个文件, 需要进行合并. 但对于Excel等复合文件格式, svn无法处理合并. 虽然云风尝试处理过<a href="http://blog.codingnow.com/2014/11/excel.html">Excel合并的问题</a>, 但其实对于我们日常开发来说, 并不太期望有些操作进行合并, 而是类似于VSS那种早期的代码管理工具的锁定行为. SVN依然有这个功能.</p> <p>这里使用的是风靡世界的TortoriseSVN. 选中一个SVN管理下的文件, 点击右键, 打开属性</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/SVN_E4B8/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/SVN_E4B8/image_thumb.png" width="583" height="204"></a></p> <p>在New对话框中选中Needs-Lock</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/SVN_E4B8/image_6.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/SVN_E4B8/image_thumb_2.png" width="350" height="199"></a></p> <p>提交这个属性修改. </p> <p>现在我们的工作流的某些步骤变化了:</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/SVN_E4B8/image_8.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/SVN_E4B8/image_thumb_3.png" width="228" height="122"></a></p> <p>getlock-&gt;modify-&gt;commit</p> <p>如果有他人在修改, getlock会失败</p> <p>getlock的原理与早期的VSS一致, 使用了文件只读的属性. 如果尝试不getlock就修改文件, 那么文件最终无法保存!</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/209943.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-06 16:27 <a href="http://www.cppblog.com/sunicdavy/archive/2015/03/06/209943.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入挖掘protobuf: 通过protoc获取proto文件信息</title><link>http://www.cppblog.com/sunicdavy/archive/2015/03/01/209894.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Sun, 01 Mar 2015 05:49:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2015/03/01/209894.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/209894.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2015/03/01/209894.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/209894.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/209894.html</trackback:ping><description><![CDATA[<p><strong>准备:</strong></p> <p>在<a title="http://code.google.com/p/protobuf/" href="http://code.google.com/p/protobuf/">http://code.google.com/p/protobuf/</a>下载protobuf-2.5版本</p> <p>预备知识: 已经使用过protobuf, 熟练应用protobuf序列化在各语言间交互信息</p> <p>目标: 获取proto内容而无需手动解析proto文件</p> <p>为proto文件添加更多的meta信息, 并在运行期获取.</p> <p>&nbsp;</p> <p><strong>protoc编译器准备</strong></p> <p>通过protobuf-2.5的源码或者从官网下载, 可以获得protoc的protobuf编译器, 这个编译器由C++编写, 官方支持完整的protobuf特性. 编译器默认支持C++, python和java 三种语言的代码生成. 如需生成更多的语言, 可以通过官网的第三方页面获取.</p> <p>&nbsp;</p> <p><strong>protoc插件原理</strong></p> <p>但我们在日常使用中, 可能需要提取proto信息, 例如: 所有的枚举,消息等信息, 字段名称和导出号. 自己编写词法解析器来做是费力不讨好的. 官方推荐的方法是使用protoc外挂插件来实现.</p> <p>protoc的插件设计比较独特, 不使用动态链接库或者java的jar包导入方式, 而是直接使用了命令行来交换数据.查看protobuf源码我们可以发现这样一个文件:</p> <p>protobuf-2.5.0\src\google\protobuf\descriptor.proto</p> <p>这个文件描述了一个proto文件的格式, 消息组成及枚举等完整信息. 这是一种自我描述的方法. </p> <p>在找到这样一个文件</p> <p>protobuf-2.5.0\src\google\protobuf\compiler\plugin.proto</p> <p>这样一个文件描述: 插件如何与protoc进行交互的协议</p> <p>protoc编译器在给定指定proto文件及搜索路径后, 将各种信息填充为descriptor.proto描述的结构后通过CodeGeneratorRequest消息系列化为二进制流后输出到命令行. 插件只用捕获protoc命令行输出的二进制流, 序列化化回CodeGeneratorRequest即可获得解析后的proto文件内容</p> <p>这里需要注意的是: 插件可执行文件很有讲究, 必须为protoc-gen-$NAME,&nbsp; 而且输出文件名参数必须为--${NAME}_out</p> <p>看一个栗子:</p> <p>protoc.exe foo.proto --plugin=protoc-gen-go=..\tools\protoc-gen-go.exe --go_out foo.go --proto_path "."</p> <p>这个栗子里: $NAME=go</p> <p>protoc将foo.proto文件(搜索路径为当前路径)的内容通过命令行输出给位于..\tools\的插件protoc-gen-go.exe,&nbsp; 输出文件名字为 foo.go</p> <p><strong>descriptor.proto信息挖掘</strong></p> <p>我们注意到在descriptor.proto文件中包含有这样的一个message: SourceCodeInfo, 这个消息体里有如下字段</p> <p>optional string leading_comments = 3;<br>&nbsp;&nbsp;&nbsp; optional string trailing_comments = 4;  <p>这两个字段对于我们获取proto文件的meta信息尤为重要, 所谓的meta信息, 理解理解为C#语言中的attribute  <p>这个attribute功能可以为一个字段, 一个消息扩充一些描述. 比如: 当一个字段通过反射显示在gui上时, gui需要获取这个字段的中文描述  <p>那么只需要如下编写  <p>optional int32 somevalue = 1 //@ desc=”中文描述”  <p>位于字段尾部的描述, 会被填充到SourceCodeInfo的 trailing_comments中, 而位于字段上方的字段, 会被填充到leading_comments中  <p>&nbsp; <p>SourceCodeInfo 并没有直接挂载在message或者字段的附近, 而是通过其下的path字段来描述与字段的关系, 这是个极为麻烦的设计.  <p>其原理如下:  <p>假设我有如下一个message  <p>message foo  <p>{  <p>&nbsp;&nbsp;&nbsp;&nbsp; optional int32 v = 1;&nbsp; // comments  <p>}  <p>要获取v后的注释, 对应的path为 4, 0, 2, 0  <p>4 表示descriptor中message_type所在的序号,由于message_type对应的类型DescriptorProto是一个数组, 所以0表示foo是在FileDescriptorProto的message_type数组类型的索引为0;  <p>如此类推: 2, 0 表示 v在DescriptorProto结构体的field成员序号为2的数组元素的索引为0  <p>&nbsp; <p><strong>如果需要更多的参考, 可以获取</strong><a title="https://github.com/golang/protobuf" href="https://github.com/golang/protobuf"><strong>https://github.com/golang/protobuf</strong></a><strong> </strong> <p>github.com\golang\protobuf\protoc-gen-go工程内有详细代码解析  <img src ="http://www.cppblog.com/sunicdavy/aggbug/209894.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-01 13:49 <a href="http://www.cppblog.com/sunicdavy/archive/2015/03/01/209894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visual Studio下的proto文件高亮插件</title><link>http://www.cppblog.com/sunicdavy/archive/2014/12/16/209189.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 16 Dec 2014 06:06:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2014/12/16/209189.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/209189.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2014/12/16/209189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/209189.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/209189.html</trackback:ping><description><![CDATA[<p>推荐一个适用于Visual Studio2013/11的Google protobuf的proto文件高亮插件, 上图</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Visual-Studio_C56E/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/Visual-Studio_C56E/image_thumb.png" width="656" height="227" /></a></p> <p>虽然没有Eclipse插件的自动生成序号功能, 但已经很漂亮了, 还自带有protobuf关键字提醒, 很不错<br />地址: https://visualstudiogallery.msdn.microsoft.com/4bc0f38c-b058-4e05-ae38-155e053c19c5</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/209189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2014-12-16 14:06 <a href="http://www.cppblog.com/sunicdavy/archive/2014/12/16/209189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>git遇到remote: fatal: early EOF + index-pack failed的处理方法</title><link>http://www.cppblog.com/sunicdavy/archive/2014/05/29/207142.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 29 May 2014 06:30:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2014/05/29/207142.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/207142.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2014/05/29/207142.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/207142.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/207142.html</trackback:ping><description><![CDATA[<p>感谢这位的博客提供的解决方法</p> <p><a title="http://www.lszhang.com/topics/git-push-%E6%97%B6%E5%87%BA%E7%8E%B0-remote-fatal-early-eof-%E9%94%99%E8%AF%AF" href="http://www.lszhang.com/topics/git-push-%E6%97%B6%E5%87%BA%E7%8E%B0-remote-fatal-early-eof-%E9%94%99%E8%AF%AF">http://www.lszhang.com/topics/git-push-%E6%97%B6%E5%87%BA%E7%8E%B0-remote-fatal-early-eof-%E9%94%99%E8%AF%AF</a></p> <p>&nbsp;</p> <p>修改 GIT 的本地 config 文件，在 core 中加入： <p>compression = -1 <p>这里是在clone方处理 <p>windows git目录在c:\Program Files (x86)\Git\etc\gitconfig中 <p>&nbsp; <p>其他辅助方法参考<a href="http://git.661346.n2.nabble.com/Large-pack-causes-git-clone-failures-what-to-do-td5481488.html">http://git.661346.n2.nabble.com/Large-pack-causes-git-clone-failures-what-to-do-td5481488.html</a> <p>git repack --max-pack-size=100m -a -d </p><img src ="http://www.cppblog.com/sunicdavy/aggbug/207142.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2014-05-29 14:30 <a href="http://www.cppblog.com/sunicdavy/archive/2014/05/29/207142.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TortoiseGit的远程拉取</title><link>http://www.cppblog.com/sunicdavy/archive/2014/04/02/206434.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 02 Apr 2014 06:17:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2014/04/02/206434.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/206434.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2014/04/02/206434.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/206434.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/206434.html</trackback:ping><description><![CDATA[<p>用惯了hg的便捷, 换做git感觉确实有些不人性化. 但是比起hg分支的反人类,git的强大还是值得我们迁移的</p> <p>这里使用TortoiseGit Windows客户端+Git-1.9.0-preview20140217.&nbsp;&nbsp; 不是使用msysgit, 理论上差异不大</p> <p>网上大多数文章都介绍如何和github进行远程拉取. 我想说, 我们开发客户端, 用github资源就是个大问题, 还更别说直接开源…</p> <p>&nbsp;</p> <p>和TortoiseHG一样, TortoiseGit也有一样的远程P2P方式拉取的方法</p> <p>只需要在一个代码库上右键菜单中选取Daemon即可</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/91192584c6b6_C6DC/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/91192584c6b6_C6DC/image_thumb.png" width="684" height="144"></a></p> <p>这里的提示告诉你, 这样的拉取无需任何的权限. 其实本地开发, 这不存在, 要的是方便, 所以果断Proceed</p> <p>&nbsp;</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/91192584c6b6_C6DC/image_4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/91192584c6b6_C6DC/image_thumb_1.png" width="807" height="349"></a></p> <p>本图表示, 你已经对外开放了你指定库的权限</p> <p>&nbsp;</p> <p>局域网的其他人选择一个空文件夹, 然后选择Clone</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/91192584c6b6_C6DC/image_6.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/91192584c6b6_C6DC/image_thumb_2.png" width="559" height="396"></a></p> <p>注意, 这里有巨大的坑, daemon中只告诉你git://你的IP/&nbsp; 但是实际拉取会出错. 正确的URL格式必须是</p> <p>git://你的IP/.git</p> <p>表示访问的git的目录!!</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/206434.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2014-04-02 14:17 <a href="http://www.cppblog.com/sunicdavy/archive/2014/04/02/206434.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自定义TexturePacker插件导出自己的plist文件</title><link>http://www.cppblog.com/sunicdavy/archive/2014/02/06/205645.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 06 Feb 2014 07:23:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2014/02/06/205645.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/205645.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2014/02/06/205645.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/205645.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/205645.html</trackback:ping><description><![CDATA[<p>cocos2dx引擎使用plist文件, 一种特殊的xml格式作为其atlas纹理的描述文件. plist遵循苹果的xml中key-value的设计风格.对于OC来说是合适的, 但xml本身性能低下, 垃圾内容过多, 也让plist对于高性能游戏引擎不再适合. 因此, 研究TexturePacker的导出插件技术</p> <p>TexturePacker的自定义插件目录位于其安装目录的bin\exporters\下, 但有一些插件属于内建支持, 例如cocos2dx的plist格式, 因此无法找到对应插件</p> <p>本人参考shiva3d插件, 对应导出界面的DataFormat中的Shiva3D, 快速学会了如何导出</p> <p>官方文档位于<a title="http://www.codeandweb.com/texturepacker/documentation/#customization" href="http://www.codeandweb.com/texturepacker/documentation/#customization">http://www.codeandweb.com/texturepacker/documentation/#customization</a></p> <p>插件的基本格式及原理是:</p> <p>bin\exporters\下的某一目录下存在的一个名为exporter.xml文件作为插件的描述,例如:</p> <div class="csharpcode"><pre class="alt"><span class="kwrd">&lt;</span><span class="html">exporter</span> <span class="attr">version</span><span class="kwrd">="1.0"</span><span class="kwrd">&gt;</span></pre><pre>    <span class="rem">&lt;!-- identifier of the exporter --&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">name</span><span class="kwrd">&gt;</span>shiva3d<span class="kwrd">&lt;/</span><span class="html">name</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt">    <span class="rem">&lt;!-- display name of the exporter for the combo box --&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">displayName</span><span class="kwrd">&gt;</span>Shiva3D<span class="kwrd">&lt;/</span><span class="html">displayName</span><span class="kwrd">&gt;</span></pre><pre class="alt">    </pre><pre>    <span class="rem">&lt;!-- description of the exporter --&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">description</span><span class="kwrd">&gt;</span>Exporter for Shiva3D.<span class="kwrd">&lt;/</span><span class="html">description</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt">    <span class="rem">&lt;!-- exporter version --&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">version</span><span class="kwrd">&gt;</span>1.0<span class="kwrd">&lt;/</span><span class="html">version</span><span class="kwrd">&gt;</span></pre><pre class="alt">    </pre><pre>    <span class="rem">&lt;!-- currently only one file allowed - more to come with update --&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">files</span><span class="kwrd">&gt;</span></pre><pre>        <span class="kwrd">&lt;</span><span class="html">file</span><span class="kwrd">&gt;</span></pre><pre class="alt">            <span class="rem">&lt;!-- name of this file variable --&gt;</span></pre><pre>            <span class="kwrd">&lt;</span><span class="html">name</span><span class="kwrd">&gt;</span>xml<span class="kwrd">&lt;/</span><span class="html">name</span><span class="kwrd">&gt;</span></pre><pre class="alt">&nbsp;</pre><pre>            <span class="rem">&lt;!-- human readable name (for GUI) --&gt;</span></pre><pre class="alt">            <span class="kwrd">&lt;</span><span class="html">displayName</span><span class="kwrd">&gt;</span>XML<span class="kwrd">&lt;/</span><span class="html">displayName</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt">            <span class="rem">&lt;!-- file extension for the file --&gt;</span></pre><pre>            <span class="kwrd">&lt;</span><span class="html">fileExtension</span><span class="kwrd">&gt;</span>xml<span class="kwrd">&lt;/</span><span class="html">fileExtension</span><span class="kwrd">&gt;</span></pre><pre class="alt">&nbsp;</pre><pre>            <span class="rem">&lt;!-- name of the template file --&gt;</span></pre><pre class="alt">            <span class="kwrd">&lt;</span><span class="html">template</span><span class="kwrd">&gt;</span>shiva.xml<span class="kwrd">&lt;/</span><span class="html">template</span><span class="kwrd">&gt;</span></pre><pre>        <span class="kwrd">&lt;/</span><span class="html">file</span><span class="kwrd">&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;/</span><span class="html">files</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt">    <span class="rem">&lt;!-- target framework supports trimming --&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">supportsTrimming</span><span class="kwrd">&gt;</span>false<span class="kwrd">&lt;/</span><span class="html">supportsTrimming</span><span class="kwrd">&gt;</span></pre><pre class="alt">&nbsp;</pre><pre>    <span class="rem">&lt;!-- target framework supports rotated sprites --&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">supportsRotation</span><span class="kwrd">&gt;</span>true<span class="kwrd">&lt;/</span><span class="html">supportsRotation</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt">    <span class="rem">&lt;!-- rotated sprites direction (cw/ccw) --&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">rotationDirection</span><span class="kwrd">&gt;</span>cw<span class="kwrd">&lt;/</span><span class="html">rotationDirection</span><span class="kwrd">&gt;</span></pre><pre class="alt">&nbsp;</pre><pre>    <span class="rem">&lt;!-- supports npot sizes --&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">supportsNPOT</span><span class="kwrd">&gt;</span>true<span class="kwrd">&lt;/</span><span class="html">supportsNPOT</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt">    <span class="rem">&lt;!-- supports file name stripping (remove .png etc) --&gt;</span></pre><pre>    <span class="kwrd">&lt;</span><span class="html">supportsTrimSpriteNames</span><span class="kwrd">&gt;</span>yes<span class="kwrd">&lt;/</span><span class="html">supportsTrimSpriteNames</span><span class="kwrd">&gt;</span></pre><pre class="alt">&nbsp;</pre><pre>    <span class="rem">&lt;!-- supports texure subpath --&gt;</span></pre><pre class="alt">    <span class="kwrd">&lt;</span><span class="html">supportsTextureSubPath</span><span class="kwrd">&gt;</span>yes<span class="kwrd">&lt;/</span><span class="html">supportsTextureSubPath</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt"><span class="kwrd">&lt;/</span><span class="html">exporter</span><span class="kwrd">&gt;</span></pre><pre>&nbsp;</pre><pre class="alt">&nbsp;</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>在Template字段中, 描述同目录的导出文件格式模板. TexturePacker使用一种叫<a href="http://www.codeandweb.com/outbound/www-grantlee-org-apidox-for_themers-html/">Grantlee</a>的模板引擎,类似于Python使用的Django模板引擎, 文档参见:<a href="http://www.codeandweb.com/outbound/www-grantlee-org-apidox-for_themers-html/">Grantlee Documentation</a>. 简单的文本格式可以参考shiva.xml快速学会</p>
<p>这里我们使用protobuf的文本格式(极为类似json)导出plist, 下面是导出模板</p>
<p>&nbsp;</p>
<div class="csharpcode"><pre class="alt">{% for sprite in allSprites %}</pre><pre>Sprite {</pre><pre class="alt">    Name: "{{sprite.trimmedName}}"</pre><pre>    FrameX: {{sprite.frameRect.x}}</pre><pre class="alt">    FrameY: {{sprite.frameRect.y}}</pre><pre>    FrameWidth: {{sprite.frameRectWithoutRotation.width}}</pre><pre class="alt">    FrameHeight: {{sprite.frameRectWithoutRotation.height}}</pre><pre>    OffsetX: {{sprite.cornerOffset.x}}</pre><pre class="alt">    OffsetY: {{sprite.cornerOffset.y}}</pre><pre>    OriginalWidth: {{sprite.untrimmedSize.width}}</pre><pre class="alt">    OriginalHeight: {{sprite.untrimmedSize.height}}</pre><pre>    {% if sprite.rotated %}Rotated: true {% endif %}</pre><pre class="alt">}</pre><pre>{% endfor %}</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>导出的结果类似于:</p>
<div class="csharpcode"><pre class="alt">&nbsp;</pre><pre>Sprite {</pre><pre class="alt">    Name: <span class="str">"car01"</span></pre><pre>    FrameX: 100</pre><pre class="alt">    FrameY: 129</pre><pre>    FrameWidth: 76</pre><pre class="alt">    FrameHeight: 47</pre><pre>    OffsetX: 0</pre><pre class="alt">    OffsetY: 0</pre><pre>    OriginalWidth: 76</pre><pre class="alt">    OriginalHeight: 47</pre><pre>    Rotated: <span class="kwrd">true</span> </pre><pre class="alt">}</pre><pre>&nbsp;</pre><pre class="alt">Sprite {</pre><pre>    Name: <span class="str">"car02"</span></pre><pre class="alt">    FrameX: 100</pre><pre>    FrameY: 51</pre><pre class="alt">    FrameWidth: 76</pre><pre>    FrameHeight: 47</pre><pre class="alt">    OffsetX: 0</pre><pre>    OffsetY: 0</pre><pre class="alt">    OriginalWidth: 76</pre><pre>    OriginalHeight: 47</pre><pre class="alt">    Rotated: <span class="kwrd">true</span> </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>...</p>
<p>导出插件还支持js扩展, 具体内容请继续参考官方文档, 但对于简单的文本格式, 这种方式已经足够了</p>
<p>对比plist后, 发现plist中的垃圾信息极为多, 而且作为spriteframe的name居然带有扩展名...&nbsp; 因此脱离plist,编写自己的导出插件才是王道!</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/205645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2014-02-06 15:23 <a href="http://www.cppblog.com/sunicdavy/archive/2014/02/06/205645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Go 1.3+ 编译器变革</title><link>http://www.cppblog.com/sunicdavy/archive/2014/01/22/205525.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 22 Jan 2014 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2014/01/22/205525.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/205525.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2014/01/22/205525.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/205525.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/205525.html</trackback:ping><description><![CDATA[<h3>概述</h3> <p>目前Go编译器是C写的，是时候换成Go啦。 <h5>背景</h5> <p>“gc"Go工具链来自Plan 9编译器的工具链。组装器、C编译器和链接器基本没变。Go的编译器(cmd/gc,cmd/5g,cmd/6g,cmd/8g)是配合工具链写的新的C程序。 <p>项目起始时，用C而不是Go写编译器有很多好处。突出的比如，首先，那时候Go还不存在，没法儿写编译器。而且实际上，就算存在，也会经常有明显的不兼容的变化。用C不用Go可以避免初始和持续开发导致的问题。然而如今Go 1已经稳定，所以这些持续的问题减少了很多。 <p>持续开发的问题已经消除，为了让Go实现的编译器比C更有吸引力，另一些工程问题出现： <ul> <li> <p>写正确的Go代码比写正确的C代码更容易。</p> <li> <p>调试错误的Go代码比调试错误的C代码更容易。</p> <li> <p>使用Go编译器需要对Go有一定理解。而用C编译器还需要一定理解C。</p> <li> <p>Go使并发执行比C更方便。</p> <li> <p>Go有更好的标准支持模块化，自动重写，单元测试和性能分析。</p> <li> <p>Go比C更有趣(fun)。</p></li></ul> <p>基于以上理由，我们相信是时候用Go写Go编译器啦。 <h5>计划设想</h5> <p>我们打算用自动化翻译工具来用Go重写现在C的编译器。这个翻译需要一些阶段，将从Go 1.3开始持续到未来的发行版。 <p>第一阶段。开发和调试一个自动化翻译工具。这可以在日常开发时同步进行。而且，人们还可以在这个阶段为C编译器继续改进。这个工具工作量很大，不过我们有信心完成这个特殊使命的工具。有许多C的观念没法儿直接转换成Go；macros(宏)，unions(联合，共用体,)，bit fields(位域)可能最先考虑。比较幸运（不是巧合），这些功能功能用的少，都会被翻译掉。指针运算和数组也需要一些转换工作，尽管编译器里很少。编译器里主要是tree(树)和linked list(链表)。翻译工具会保留注释和C代码的结构，所以翻译后的代码和当前的编译器代码一样可阅读。 <p>第二阶段。用翻译工具转换C代码到Go，并删除C源码。这时我们已经开始翻译，但是Go还是运行在C编译器上。非常乐观的，这可能发生在Go 1.3。不过更可能是Go 1.4。 <p>第三阶段。使用一些工具，可能来自gofix和the Go oracle，拆分编译器到包，清理和文档化代码，添加适当的单元测试。这是编译器会是地道的Go程序。目前打算在Go 1.4实现。 <p>第四a阶段。使用标准的分析和测试工具优化编译器的CPU和内存使用。可能要引入并行。如果真这样，<a href="http://blog.golang.org/race-detector">Race Detector</a>(Go的并行竞争检测工具,)会有很大帮助。这目标在Go 1.4，可能部分会延后到1.5。基本的优化分析会在第三阶段完成。 <p>第四b阶段。（和四a几段同时进行）当编译器依照明显的界限分割成包之后，需要明确引入一个中介码，在结构无关的无序树(Node_s)和结构相关的有序链表(Prog_s)之间。这个中介码应该不依赖整体架构，但是包含准确的执行顺序信息，可以用于有顺序但是结构无关的操作的优化，比如清理多余的nil检测和出界检测。这些过程基于<a href="http://en.wikipedia.org/wiki/Static_single_assignment_form">SSA</a>（静态单赋值），你可以从Alan Donovan的 go.tools/ssa 包中了解更多。 <p>第五阶段。替换go/parser和go/types到最新（全新）的版本。Robert Griesemer参考现在的经验，讨论了设计新的parser和types的可能。如果联系他们到编译器后端，相信对设计新的API有很大帮助。 <p><strong>自展（Bootstrapping）</strong>用Go语言实现的Go的编译器，从一开始就要考虑如何自展。我们考虑的规则就是Go1.3编译器必须由Go1.2编译，Go1.4的编译器必须由Go1.4编译，以此类推。 <p>这时，我们就有了一个清晰的流程来生成当前的程序：编译Go1.2的工具链（由C编写），然后使用它编译Go1.3的工具链，以此类推。这里需要一个脚本来做这个事情，来保证只会消耗CPU的时间而非某个人的时间。这样的自展，每个机器只会做一次，Go1.x的工具链将会在本地保留，并在执行all.bash来编译Go1.(x+1)工具链的时候被再次使用。 <p>显然，随着时间的推移这种自举方式是不充分的。在后面的多个版本被发布之前，为编译器写一个后端来生成C代码也许是一个更有意义的事情。这些C代码不要求效率或可读性，只要正确即可。这些C代码将会被签入，就像我们签入由yacc生成的y.tab.c文件一样。这样，自展过程就会变成：先用gcc编译C代码生成一个自展编译器，然后使用这个自展编译器来编译真正的编译器。类似于另一个自展过程，这个自展编译器将会在本地保留，并在每次执行all.bash的时候重复使用（不用重新编译）。 <p><strong>替代选择</strong>还有一些比较明显的替代方案，需要我们说明一下为什么放弃了这些选择。 <p>从一开始写一个编译器。现在的编译器有一个非常重要的特征：他们能够正常工作（或者其至少能够满足所有用户的要求）。尽管Go语言比较简单，但是编译器中有很多细微的细节优化和改写，直接丢弃10或数年的在这上面的努力是比较愚蠢的。 <p>对编译器进行人工翻译。我们已经以人工的方式翻译了一小部分C/C++代码到Go语言了。这个过程是枯燥而且易错的，且这些错误非常的细微及难以发现。相反，使用机械翻译会形成一些比较一致的错误，而这些错误是易于发现的；而且不会因为枯燥的过程开小差。Go编译器的代码明显的比我们翻译的代码多很多：超过60,000行C代码，机械翻译会使这个过程容易一些。就像Dick Sites在1974年说的一样：“相比写程序，我宁愿写一个程序来帮我写程序。“ 使用机械来翻译编译器也方便于在准备好切换之前，我们可以继续开发完善现有的C程序。 <p>只翻译后端并链接到go/parser和go/types.从前端传给后端的数据结构所包含的信息中，go/parser和go/types所能提供的除了API就没其他的东西了。如果使用这些库来替代前端，需要写代码来转换go/parser和go/types所能提供数据结构到后端，这是一个非常宽泛且易出错的工作。我们相信使用这些库是有意义的，但更明智的是，等到将编译器代码调整的更像Go程序，分成确定边界的、包含说明文档和单元测试子包之后再使用。 <p>放弃现有的编译器，使用gccgo（或者go/parser + go/types + LLVM, …）。现有的编译器是Go语言显得比较灵活的一个重要组成部分。如果尝试使用基于大量代码的GCC或LLVM来开发Go程序，感觉会有碍到Go语言的灵活性。另外，GCC是大量C代码（现在有部分C++）、LLVM是大量C++代码的程序。以上列举的、用于解释不使用现有编译框架代码的几个原因，也都适用于更多的类似的代码库。 <h5>C语言的长期使用</h5> <p>临近结束，这个计划还留下了由C写成的Plan9的工具链的一部分。在长期发展中，还是将所有的C从代码树排除掉比较好。本章节推测了一下这件事将会如何发生，但不保证其指定会发生或者按照这种套路发生。 <p>运行时包(runtime)。 runtime包的大部分都是用C写成，基于一些同样的原因，Go编译器也是用C实现。但是，runtime包远比编译器的代码量要小，且它现在已经是用Go和C混合编写。将C代码转换为Go代码时，一次转化一部分貌似也是可行的。其中，主要部分有：调度器（scheduler），垃圾回收（the garbage collector），散列映射表（hash map）的实现，和channel的实现。（这里Go和C代码混合的很融洽，是因为这里使用的6c而不是gcc来编译的C代码。） <p>C编译器。 Plan 9的C编译器本身就是用C写成，如果我们要从Go包实现里面移除所有的C代码，那么我们将移除这些编译工具：“go tool 6c”等等，另外，.c的文件也将不被支持出现的Go包的目录里面。我们应该提前声明这样的计划，以便使用C的第三方包有时间去移除这类C代码的使用。（Cgo，由于使用了gcc来替代6c，所以它仍然可以作为一个途径来在Go包中使用C实现部分功能。）在Go1的兼容性文档中没有包含工具链修改的描述，也就是说去掉C编译器是被允许的。 <p>汇编器。 Plan 9的汇编器也是用C实现的，但这个汇编器只不过是一系列解析树组成的简单解析器，这使得不论手动还是自动将它翻译成Go语言都比较简单。 <p>连接器。 Plan 9的连接器也是由C写成。最近的一些工作，已经将大部分的连接器工作放到的编译器中，而且，也已经有个计划将剩余的部分重写成一个新的、更简单的Go程序。转移到编译器的部分连接器代码，现在需要随着编译器的原有代码一起进行翻译。 <p>基于Libmach的工具: nm, pack, addr2line, 和objdump。 Nm现在已经使用Go语言重写。Pack和addr2line可以任何一天被重写。Objdump现在依赖于libmach的反汇编器，但这些转换为Go也是比较简单的，不论是使用机械还是人工翻译。所以基于这几点，libmach本身将来也可以被移除。 <p>&nbsp; <p>来源: <a href="http://www.oschina.net/translate/go-1-3-compiler-overhaul">http://www.oschina.net/translate/go-1-3-compiler-overhaul</a> <p>英文来源:<a title="https://docs.google.com/document/d/1P3BLR31VA8cvLJLfMibSuTdwTuF7WWLux71CYD0eeD8/preview?sle=true&amp;pli=1" href="https://docs.google.com/document/d/1P3BLR31VA8cvLJLfMibSuTdwTuF7WWLux71CYD0eeD8/preview?sle=true&amp;pli=1">https://docs.google.com/document/d/1P3BLR31VA8cvLJLfMibSuTdwTuF7WWLux71CYD0eeD8/preview?sle=true&amp;pli=1</a></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/205525.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2014-01-22 12:23 <a href="http://www.cppblog.com/sunicdavy/archive/2014/01/22/205525.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows下protoc-gen-go的使用方法(goprotobuf)</title><link>http://www.cppblog.com/sunicdavy/archive/2014/01/21/205517.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 21 Jan 2014 08:22:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2014/01/21/205517.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/205517.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2014/01/21/205517.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/205517.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/205517.html</trackback:ping><description><![CDATA[<p>goprotobuf是go语言中写的较好的一个实现, linux下的安装非常方便, 但是windows需要添加plugin的路径才能识别</p> <p>先确认你已经设置好GOPATH, 并安装好goprotobuf</p> <p>我的goprotobuf路径是标准的: $GOPATH/src/code.google.com/p/goprotobuf</p> <p><strong>编译并安装proto工具:</strong></p> <p>go install code.google.com/p/goprotobuf/proto <p>go install code.google.com/p/goprotobuf/protoc-gen-go <p>确认$GOPATH/bin下有protoc-gen-go.exe <p>&nbsp; <p><strong>编译proto文件输出go文件:</strong> <p>使用命令行编译path/to/protoc.exe&nbsp; --plugin=protoc-gen-go=$GOPATH\bin\protoc-gen-go.exe --go_out . --proto_path .&nbsp; XXX.proto <p>这里顺便贴出notepad++使用nppexec插件的command <p>"path/to/protoc.exe"&nbsp; --plugin=protoc-gen-go=path/to/gopath/bin/protoc-gen-go.exe --go_out $(CURRENT_DIRECTORY) --proto_path $(CURRENT_DIRECTORY)&nbsp; $(FULL_CURRENT_PATH)  <p>P.S. <p>protoc请自行在<a href="https://code.google.com/p/protobuf/">protobuf官网</a>下载C++源码后编译</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/205517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2014-01-21 16:22 <a href="http://www.cppblog.com/sunicdavy/archive/2014/01/21/205517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Qt技术优势</title><link>http://www.cppblog.com/sunicdavy/archive/2014/01/14/205359.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 14 Jan 2014 03:53:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2014/01/14/205359.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/205359.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2014/01/14/205359.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/205359.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/205359.html</trackback:ping><description><![CDATA[<p>1. Qt这个C++的图形库由Trolltech在1994年左右开发。它可以运行在Windows,Mac OS X, Unix，还有像Sharp Zaurus这类嵌入式系统中。Qt是完全面向对象的。 <p>2. Qt的架构明显是经过精心设计的面向对象的。Qt因此在命名，继承，类的组织等方面保持了优秀的一致性。你只需要提供唯一一个方法的参数，仅此一个。在不同的类中调用方式也是有很强的连贯性。返回值也很有逻辑性。所有一切达到了简单和强大的和谐统一。一旦你使用了其中一个类，其他的类也就触类旁通，因为他们是一致的。 <p>3. Qt不强制使用任何设计模式。如果你认为恰当，使用Document/view没有任何问题。不使用也没有任何问题。 <p>4. MFC是事件驱动的架构。要执行任何操作，都必须是对特定的消息作出响应。Windows对应用程序发送的信息数以千计，遗憾的是，要分清楚这些分繁芜杂的消息是很困难的，并且关于这方面的文档并不能很好的解决这些问题。<br>Qt的消息机制是建立在SIGNAL()发送和SLOT()接受的基础上的。这个机制是对象间建立联系的核心机制。利用SIGNAL()可以传递任何的参数。他的功能非常的强大。可以直接大传递信号给SLOT()，因此可以清楚的理解要发生的事情。一个类所发送的信号的数量通常非常的小(4或者5)，并且文档也非常的齐全。这让你感觉到一切尽在掌握之中。SIGNAL/SLOT机制类似于Java中listener机制,不过这种机制更加轻量级，功能更齐全。 <p>5. Qt拥有非常简单而又不失强大的layout机制，布局灵活多变<br>Qt还提供了一个图形用户工具，Qt Designer，可以用来帮助建立用户界面。可以修改所使用的任何控件的属性。不用将他们放在严格的位置，可以通过layout完美的组织他们。这个工具所产生的代码我们是可以实际上阅读并且可以理解的。生成的代码单独放在一个文件里，在编程的同时，你可以随心所欲的多次重新生成用户界面。<br>Qt Designer可以让你完成许多在MFC中不可能完成的任务，比如用预先填好的生成listview，在每个tab上用不同的view来使用tab 控制。 <p>6. 使用MFC，一部分开发过程要依靠“resources”,在很多的案例中开发者必须使用他们。这样会导致如下的后果：出了Visual Studio，你很难使用其他的工具来完成开发。<br>资源编辑器仅有有限的功能，比如：通过Dialog编辑器不可能改变所有的属性，一些属性可以改变，另一些属性则不可能改变。(译者注：下面还有两条陈述MFC缺点的实例，但我感觉这些已经够说明问题了，暂时删节不译)<br>然而Qt并没有资源的概念，这就解决了以上所提到的问题。Qt提供了一个脚本使得能将编入你的代码。对于界面设计，Qt Designer则创建了可读的代码。 <p>7. Qt的文档完备且详细的覆盖了Qt的方方面面，竟然仅有18M。每一个类和方法都被详尽描述，巨细靡遗，举例充实。通过Trolltech公司提供的链接或者是Qt Assistant工具，可以方便的从一个类或者方法跳转到其他的类。文档还包含了一个初学者教程和一些典型应用的例子 <p>8. 在发布基于MFC的软件时，必须依靠存在于客户电脑上的MFC。但是这是不安全的，同样是MFC42.dll，可以基于相同的库得到3个不同的版本。通常，需要检查是否拥有正确的MFC42.dll版本，如果不是，就升级它。但是升级MFC42.dll会改变很多软件的行为。<br>Qt则没有这个风险，因为Qt压根就没有“升级整个系统”这个概念。 <p>9. Qt 完全支持CSS2，这使得Qt应用程序，无论是美化还是换肤，实现起来都相当简单 <p>10. Qt自带翻译器，可以随意切换软件语言 <p>&nbsp; <p>在使用Qt动态链接库的情况下，根据LGPL协议规定，是可以闭源发布任何形式的程序的。 <p>参考链接： <p>来自Qt官方论坛的讨论：<a href="http://qt-project.org/forums/viewthread/2428">http://qt-project.org/forums/viewthread/2428</a> <p>博客链接：<a href="http://devbean.blog.51cto.com/448512/313477">http://devbean.blog.51cto.com/448512/313477</a> <p>&nbsp; <p>&nbsp; <p>转自:<a href="http://blog.csdn.net/superzhaifd/article/details/18224923">http://blog.csdn.net/superzhaifd/article/details/18224923</a>&nbsp;<a href="http://blog.csdn.net/superzhaifd">翟冬狼_Trump</a> <p>&nbsp; <p>本人较喜欢第二点: 不使用任何设计模式构建底层. 设计模式只是思想, 也是羁绊. 大量使用只会让系统臃肿.</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/205359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2014-01-14 11:53 <a href="http://www.cppblog.com/sunicdavy/archive/2014/01/14/205359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>让VC助手在外部文件变化时自动parse</title><link>http://www.cppblog.com/sunicdavy/archive/2013/11/13/204237.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 13 Nov 2013 02:39:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2013/11/13/204237.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/204237.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2013/11/13/204237.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/204237.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/204237.html</trackback:ping><description><![CDATA[<p>我们的工程使用notepad++挂载protobuf的protoc代码生成器, 每次生成后, 助手都要手动parse一次, 很麻烦. 研究了下VC助手的选项, 按下图配置即可静默刷新文件</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/VCparse_94D9/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/VCparse_94D9/image_thumb.png" width="570" height="175"></a></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/204237.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2013-11-13 10:39 <a href="http://www.cppblog.com/sunicdavy/archive/2013/11/13/204237.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC工程的命令行编译法</title><link>http://www.cppblog.com/sunicdavy/archive/2013/11/05/204099.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 05 Nov 2013 07:20:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2013/11/05/204099.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/204099.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2013/11/05/204099.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/204099.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/204099.html</trackback:ping><description><![CDATA[<p>我使用的是VS2010, 老版本的未测</p> <p>call "c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"<br>&nbsp;&nbsp;&nbsp; cd 你的工程sln目录</p> <p>MSBuild “你的工程.sln” /t:Build /p:Configuration=Release /maxcpucount:4</p> <p>解释: 首先调用VC上下文建立批处理, 转到你的sln目录,保证工作目录正确, /maxcpucount是并行编译, 根据你的需求配置即可</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/204099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2013-11-05 15:20 <a href="http://www.cppblog.com/sunicdavy/archive/2013/11/05/204099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用HG(Mercurial)做分布式代码管理的一些经验</title><link>http://www.cppblog.com/sunicdavy/archive/2013/10/25/203915.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 25 Oct 2013 14:51:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2013/10/25/203915.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/203915.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2013/10/25/203915.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/203915.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/203915.html</trackback:ping><description><![CDATA[<p>距离第一次使用HG已经由2,3年了。 从第一次将HG用于自己的项目， 用U盘同步代码. 到现在将HG应用于linux, 版本差异发布, 项目内部多人的分布式开发，已经感觉非常熟练。</p> <p>我们的项目的客户端和服务器均由C++开发，由于HG设计的理念是1个工程对应1个库， 因此我们的客户端和服务器是分开的两个HG代码库。这种思想和SVN管理的代码有很大不同。SVN时代的游戏工程大多是这样安排目录的：</p> <p>common &lt;-客户端和服务器共享的库</p> <p>client&lt;-客户端的代码</p> <p>server&lt;-服务器的代码</p> <p>通过SVN强大的权限控制给不同的前后端赋予权限，前后端程序将获得不同的目录组合。SVN下的这种工程组织方法能很好的解决单一语言跨工程的代码，协议共享问题。虽然现在各种Erlang，Java的服务器语言与as3,lua的不同客户端脚本语言混杂的时代已经无所谓这种老式设计思想。但是对于我们纯C++的手游来说，还是必须面对分布式代码管理工具下的代码跨库共享问题。</p> <p>我就这个问题与多年前被我推荐过HG的朋友讨论起来，他们也存在我们这个问题，但是他们的解决方法就是每个工程一个库。然后被我问到：“同步一次代码，一次次的打开不同的库（他们客户端+服务器一共6到7个HG代码库），进行同步， 完成后， 还要反向pull，不累啊？”， 朋友回答：“习惯就好”</p> <p>随后，我也翻查了git对多项目的支持。得到的答案也是跟HG一样的， 这类分布式代码管理工具本身的设计理念只有账号，而无权限， 本身就是基于开源代码精神设计的工具， 如果分了权限，岂不是违背开源精神（这是我想的<img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" alt="微笑" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/09a081eb5d4c_13A7F/wlEmoticon-smile_2.png">）。因此如果想管理多个项目代码， 要么多库，要么合库。</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/203915.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2013-10-25 22:51 <a href="http://www.cppblog.com/sunicdavy/archive/2013/10/25/203915.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序异常VC调试器无法定位的处理</title><link>http://www.cppblog.com/sunicdavy/archive/2013/06/27/201339.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 27 Jun 2013 03:05:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2013/06/27/201339.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/201339.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2013/06/27/201339.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/201339.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/201339.html</trackback:ping><description><![CDATA[<p>最近调试程序发现空指针老无法定位, 使用一个最简单的main函数做空指针检查也一样, 具体症状见图</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Visual-Studio_9AF3/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Visual-Studio_9AF3/image_thumb.png" width="749" height="439"></a></p> <p>pdb加载是正常的, 但是堆栈没显示如此简单的空指针访问位置. Google了以下</p> <p><a href="http://blogs.msdn.com/b/debugger/archive/2010/05/12/visual-studio-debugger-fails-to-catch-unhandled-exception-for-a-windows-form-or-wpf-application.aspx">http://blogs.msdn.com/b/debugger/archive/2010/05/12/visual-studio-debugger-fails-to-catch-unhandled-exception-for-a-windows-form-or-wpf-application.aspx</a></p> <p>解决方法: Debug-&gt;Exception中将所有异常勾选即可</p> <p>&nbsp;</p> <p>不知道哪里的设置导致如此诡异的问题, 害的我重装一次..</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/201339.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2013-06-27 11:05 <a href="http://www.cppblog.com/sunicdavy/archive/2013/06/27/201339.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2D游戏必备的TexturePacker</title><link>http://www.cppblog.com/sunicdavy/archive/2013/06/05/200812.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 05 Jun 2013 07:44:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2013/06/05/200812.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/200812.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2013/06/05/200812.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/200812.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/200812.html</trackback:ping><description><![CDATA[&nbsp; &nbsp;最近开始弄cocos2dx, 图片需要整合成POT的优化纹理, 使用texturePacker来做<br />
下载<a href="http://www.codeandweb.com/texturepacker/download">http://www.codeandweb.com/texturepacker/download<br />
</a>工具本身不是免费的, 但是可以通过申请获得免费的Licence, 点<a href="http://www.codeandweb.com/request-free-license">这里</a>看<br />
条件是有一个自己的博客, 并且从事游戏/软件/网页方面的开发, 且近期有5篇文章发表<br />
作者特别强调，微博不等于博客<br />
<br />
填写好邮箱地址，要不了几个小时就可以获取到序列号<img src ="http://www.cppblog.com/sunicdavy/aggbug/200812.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2013-06-05 15:44 <a href="http://www.cppblog.com/sunicdavy/archive/2013/06/05/200812.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Lisp的永恒之道</title><link>http://www.cppblog.com/sunicdavy/archive/2012/06/12/178505.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 12 Jun 2012 04:38:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2012/06/12/178505.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/178505.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2012/06/12/178505.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/178505.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/178505.html</trackback:ping><description><![CDATA[<h5>本文转自: <a href="http://coolshell.cn/articles/7526.html">http://coolshell.cn/articles/7526.html</a></h5> <p>&nbsp;</p> <h5>Lisp之魅</h5> <p>长久以来，Lisp一直被许多人视为史上最非凡的编程语言。它不仅在50多年前诞生的时候带来了诸多革命性的创新并极大地影响了后来编程语言的发展，即使在一大批现代语言不断涌现的今天，Lisp的诸多特性仍然未被超越。当各式各样的编程语言摆在面前，我们可以从运行效率、学习曲线、社区活跃度、厂商支持等多种不同的角度进行评判和选择，但我特别看中的一点在于语言能否有效地表达编程者的设计思想。学习C意味着学习如何用过程来表达设计思想，学习Java意味着学习如何用对象来表达设计思想，而虽然Lisp与函数式编程有很大的关系，但学习Lisp绝不仅仅是学习如何用函数表达设计思想。实际上，<strong>函数式编程并非Lisp的本质</strong>，在已经掌握了lambda、高阶函数、闭包、惰性求值等函数式编程概念之后，学习Lisp仍然大大加深了我对编程的理解。<strong>学习Lisp所收获的是如何“自由地”表达你的思想</strong>，这正是Lisp最大的魅力所在，也是这门古老的语言仍然具有很强的生命力的根本原因。 <h5>Lisp之源</h5> <p>Lisp意为表处理(List Processing)，源自设计者John McCarthy于1960年发表的一篇论文《符号表达式的递归函数及其机器计算》。McCarthy在这篇论文中向我们展示了用一种简单的数据结构S表达式(S-expression)来表示代码和数据，并在此基础上构建一种完整的语言。Lisp语言形式简单、内涵深刻，Paul Graham在《Lisp之根源》中将其对编程的贡献与欧几里德对几何的贡献相提并论。 <h5>Lisp之形</h5> <p>然而，与数学世界中简单易懂的欧氏几何形成鲜明对比，程序世界中的Lisp却一直是一种古老而又神秘的存在，真正理解其精妙的人还是少数。从表面上看，Lisp最明显的特征是它“古怪”的S表达式语法。S表达式是一个原子(atom)，或者若干S表达式组成的列表(list)，表达式之间用空格分开，放入一对括号中。“列表“这个术语可能会容易让人联想到数据结构中的链表之类的线形结构，实际上，Lisp的列表是一种可嵌套的树形结构。下面是一些S表达式的例子:<pre>foo

()

(a b (c d) e)

(+ (* 2 3) 5)

(defun factorial (N)
    (if (= N 1)
        1
        (* N (factorial (- N 1)))
    )
)
</pre>
<p>据说，这个古怪的S表达式是McCarthy在发明Lisp时候所采用的一种临时语法，他实际上是准备为Lisp加上一种被称为M表达式(M-expression)的语法，然后再把M表达式编译为S表达式。用一个通俗的类比，S表达式相当于是JVM的字节码，而M表达式相当于Java语言，但是后来Lisp的使用者都熟悉并喜欢上了直接用S表达式编写程序，并且他们发现S表达式有许多独特的优点，所以M表达式的引入也就被无限期延迟了。
<p>许多Lisp的入门文章都比较强调Lisp的函数式特性，而我认为这是一种误导。真正的Lisp之门不在函数式编程，而在S表达式本身，Lisp最大的奥秘就藏在S表达式后面。S表达式是Lisp的语法基础，语法是语义的载体，形式是实质的寄托。<strong>“S表达式”是程序的一种形，正如“七言”是诗的一种形，“微博”是信息的一种形</strong>。正是形的不同，让微博与博客有了质的差异，同样的道理，正是S表达式让Lisp与C、Java、SQL等语言有了天壤之别。
<h5>Lisp之道</h5>
<p>一门语言能否有效地表达编程者的设计思想取决于其抽象机制的语义表达能力。根据抽象机制的不同，语言的抽象机制形成了面向过程、面向对象、函数式、并发式等不同的范式。当你采用某一种语言，基本上就表示你已经“面向XXX“了，你的思维方式和解决问题的手段就会依赖于语言所提供的抽象方式。比如，采用Java语言通常意味着采用面向对象分析设计；采用Erlang通常意味着按Actor模型对并发任务进行建模。
<p>有经验的程序员都知道，无论是面向XXX编程，程序设计都有一条“抽象原则“：What与How解耦。但是，<strong>普通语言的问题就在于表达What的手段非常有限</strong>，无非是过程、类、接口、函数等几种方式，而诸多领域问题是无法直接抽象为函数或接口的。比如，你完全可以在C语言中定义若干函数来做到make file所做的事情，但C代码很难像make file那样声明式地体现出target、depends等语义，它们只会作为实现细节被淹没在一个个的C函数之中。采用OOP或是FP等其它范式也会遇到同样的困难，也就是说make file语言所代表的抽象维度与面向过程、OOP以及FP的抽象维度是正交的，使得各种范式无法直接表达出make file的语义。这就是普通语言的“刚性”特征，它要求我们必须以语言的抽象维度去分析和解决问题，把问题映射到语言的基本语法和语义。
<p>更进一步，如果仔细探究这种刚性的根源，我们会发现正是由于普通语言<strong>语法和语义的紧耦合</strong>造成了这种刚性。比如，C语言中printf(“hello %s”, name)符合函数调用语法，它表达了函数调用语义，除此之外别无他义；Java中interface IRunnable { … }符合接口定义语法，它表达了接口定义语义，除此之外别无他义。如果你认为“语法和语义紧耦合“是理所当然的，看不出这有什么问题，那么理解Lisp就会让你对此产生更深的认识。
<p>当你看到Lisp的(f a (b c))的时候，你会想到什么？会不会马上联想到函数求值或是宏扩展？就像在C语言里看到gcd(10, 15)马上想到函数调用，或者在Java里看到class A马上想到类定义一样。如果真是这样，那它就是你理解Lisp的一道障碍，因为你已经习惯了顺着语言去思考，总是在想这一句话机器怎么解释执行？那一句话又对应语言的哪个特性？理解Lisp要反过来，让语言顺着你，Lisp的(f a (b c))可以是任何语义，完全由你来定，它可以是函数定义、类定义、数据库查询、文件依赖关系，异步任务的执行关系，业务规则 …
<p>下面我准备先通过几个具体的例子逐步展示Lisp的本质。需要说明的是，由于Lisp的S表达式和XML的语法形式都是一种树形结构，在语义表达方面二者并无本质的差别。所以，为了理解方便，下面我暂且用多数人更为熟悉的XML来写代码，请记住我们可以很轻易地把XML代码和Lisp代码相互转换。
<p>首先，我们可以轻易地用XML来定义一个求两个数最大公约数的函数：<pre>    &lt;func name='gcd' return_type='int'&gt;
        &lt;params&gt;
            &lt;a type='int'/&gt;
            &lt;b type='int'/&gt;
        &lt;/params&gt;
        &lt;body&gt;
            &lt;if&gt;
               &lt;equals&gt;
                   &lt;a/&gt;
                   &lt;int&gt;0&lt;/int&gt;
               &lt;/equals&gt;
            &lt;/if&gt;
            &lt;then&gt;
                &lt;return&gt;&lt;b/&gt;&lt;/return&gt;
            &lt;/then&gt;
            &lt;else&gt;
                &lt;return&gt;
                    &lt;gcd&gt;
                        &lt;modulo&gt;&lt;b/&gt;&lt;a/&gt;&lt;/modulo&gt;
                        &lt;a/&gt;
                    &lt;/gcd&gt;
                &lt;/return&gt;
            &lt;/else&gt;
        &lt;/body&gt;
    &lt;/func&gt;
</pre>
<p>其次，我们可以用它来定义类：<pre>    &lt;class name="Computer"&gt;
        &lt;field access="private" type="MainBoard" name="main-board" /&gt;
        &lt;field access="private" type="CPU" name="cpu" /&gt;
        &lt;field access="private" type="Memory" name="memory" /&gt;

        &lt;method access="public" return_type="boolean" name="powerOn" /&gt;
            &lt;params&gt;...&lt;/params&gt;
            &lt;body&gt;...&lt;/body&gt;
        &lt;/method&gt;

        &lt;method access="public" return_type="boolean" name="powerOff" /&gt;
            &lt;params&gt;...&lt;/params&gt;
            &lt;body&gt;...&lt;/body&gt;
        &lt;/method&gt;
    &lt;/class&gt;
</pre>
<p>还可以轻易地用它来编写关系查询：<pre>&lt;sql&gt;
    &lt;select&gt;
        &lt;column name="employees.id" /&gt;
        &lt;column name="bonus.amount" /&gt;
    &lt;/select&gt;
    &lt;from&gt;
        &lt;table name="employees" /&gt;
        &lt;table name="bonus" /&gt;
    &lt;/from&gt;
    &lt;where&gt;
        &lt;equals&gt;
            &lt;column name="employees.id" /&gt;
            &lt;column name="bonus.employee_id" /&gt;
        &lt;/equals&gt;
    &lt;/where&gt;
&lt;/sql&gt;
</pre>
<p>还可以用它来实现类似make file的自动化构建(语法取自ant)：<pre>    &lt;project name="MyProject" default="dist" basedir="."&gt;
        &lt;property name="src" location="src"/&gt;
        &lt;property name="build" location="build"/&gt;
        &lt;property name="dist"  location="dist"/&gt;

        &lt;target name="init"&gt;
            &lt;mkdir dir="${build}"/&gt;
        &lt;/target&gt;

        &lt;target name="compile" depends="init" description="compile the source " &gt;
            &lt;javac srcdir="${src}" destdir="${build}"/&gt;
        &lt;/target&gt;

        &lt;target name="dist" depends="compile" description="generate the distribution" &gt;
            &lt;mkdir dir="${dist}/lib"/&gt;
            &lt;jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/&gt;
        &lt;/target&gt;

        &lt;target name="clean" description="clean up" &gt;
            &lt;delete dir="${build}"/&gt;
            &lt;delete dir="${dist}"/&gt;
        &lt;/target&gt;
    &lt;/project&gt;
</pre>
<p>一口气举了这么多个例子，目的在于用XML这种树形结构来说明Lisp的S表达式所能够描述的语义。不知道你是否发现了S表达式和XML这种树形语法在语义构造方面有着特别的“柔性”？我们可以轻易地用它构造出函数、变量、条件判断语义；类、属性、方法语义；可以轻易地构造出关系模型的select、where语义；可以轻易地构造出make的target、depends语义，等等数不清的语义。在普通语言里，你可以定义一个函数、一个类，但你无法为C语言增加匿名函数特性，也没法给Java语言加上RAII语义，甚至连自己创造一个foreach循环都不行，而自定义语义意味着在Lisp之上<strong>你创造了一门语言</strong>！不管是面向过程，面向对象，函数式，还是关系模型，在Lisp里统统都变成了一种DSL，而Lisp本身也就成了一种定义语言的语言，即元语言(Meta Language)。
<p>Lisp的柔性与S表达式有着密切的关系。Lisp并不限制你用S表达式来表达什么语义，同样的S表达式语法可以表达各种不同领域的语义，这就是<strong>语法和语义解耦</strong>。如果说普通语言的刚性源于“语法和语义紧耦合”，那么Lisp的柔性正是源于“语法和语义解耦”！“语法和语义解耦”使得Lisp可以随意地构造各种领域的DSL，而不强制用某一种范式或是领域视角去分析和解决问题。本质上，Lisp编程是一种超越了普通编程范式的范式，这就是<strong>Lisp之道：面向语言编程(LOP, Language Oriented Programming)</strong>。Wikipedia上是这样描述LOP的：
<blockquote>
<p>Language oriented programming (LOP) is a style of computer programming in which, rather than solving problems in general-purpose programming languages, the programmer creates one or more domain-specific languages for the problem first, and solves the problem in those languages … The concept of Language Oriented Programming takes the approach to capture requirements in the user’s terms, and then to try to create an implementation language as isomorphic as possible to the user’s descriptions, so that the mapping between requirements and implementation is as direct as possible.</p></blockquote>
<p>LOP范式的基本思想是从问题出发，先创建一门描述领域模型的DSL，再用DSL去解决问题，它具有高度的声明性和抽象性。SQL、make file、CSS等DSL都可以被认为是LOP的具体实例，下面我们再通过两个常见的例子来理解LOP的优势。
<p>例1：在股票交易系统中，交易协议定义若干二进制的消息格式，交易所和客户端需要对消息进行编码和解码。
<p>消息格式是一种抽象的规范，本身不对语言做任何的限制，你可以用C，C++，Java，或者Python。普通的实现方式是按照消息格式规范，在相应的语言中定义消息结构，并编写相应的编解码函数。假设为一个消息定义结构和实现编解码函数的工作量为M，不同消息类型的数量为N，这种方式的工作量大致为M*N。也就是说每增加一种消息类型，就需要为该消息定义结构，实现编解码函数，引入bug的可能性当然也和M*N成正比。如果仔细观察不难发现，各个消息结构其实是高度类似的，编解码函数也大同小异，但是普通语言却找不到一种抽象机制能表达这种共性，比如，我们无法通过面向对象的方法定义一个基类把消息结构的共性抽象出来，然后让具体的消息去继承它，达到复用的目的。这正是由于普通语言的抽象维度限制所致，在普通语言中，你只能从函数、接口等维度对事物进行抽象，而恰好消息格式共性所在的维度与这些抽象维度并不匹配。
<p>其实，不同消息类型的<strong>共性在于它们都具有相同的领域语义</strong>，比如：“某字段内容是另一个字段内容的md5码”就是一种消息格式的领域语义，这种领域语义是OOP的抽象机制无法描述的。LOP的思路是先创建一门消息定义DSL，比如，类似Google的Protocol Buffer，Android的AIDL。然后，通过DSL编写消息定义文件，直接声明式地描述消息的结构特征，比如，我们可以声明式地描述“某字段内容是另一个字段内容的md5码”。我们还需要为DSL开发编译器用于生成C、Java等通用语言的消息定义和编解码函数。
<p>有了消息定义DSL和编译器之后，由于DSL编写消息定义是一种高度声明式的编程方法，每增加一种消息的只需要多编写一个消息定义文件而已，工作量几乎可以忽略不计。所有的工作量都集中在编译器的开发上，工作量是一个常数C，与消息的数量没有关系；质量保证方面也只需要关注编译器这一点，不会因为增加新的消息类型而引入bug。
<p>例2：在图书管理系统中，需要支持在管理界面上对书籍、学生、班级等各种实体进行管理操作。
<p>如果按传统的三层架构，一般需要在后端程序中为每一种实体定义一个类，并定义相应的方法实现CRUD操作，与之相应的，还需要在前端页面中为每一个实体编写相应的管理页面。这些实体类的CRUD操作都是大同小异的，但细节又各不相同，虽然我们很想复用某些共同的设计实现，但OOP所提供的封装、继承、多态等抽象机制不足以有效捕获实体之间的共性，大量的代码还是必须放在子类中来完成。比如，Student和Book实体类的实现非常相似，但是如果要通过OOP的方式去抽象它们的共性，得出的结果多半是Entity这样的大而空的基类，很难起到复用的效果。
<p>其实，不同实体之间的共性还是在于它们具有相同的领域语义，比如：实体具有属性，属性具有类型，属性具有取值范围，属性具有可读取、可编辑等访问属性，实体之间有关联关系等。LOP方法正是直接面向这种领域语义的。采用LOP方法，我们并不需要为每一个实体类单独编写CRUD方法，也不需要单独编写管理页面，只需要定义一种DSL并实现其编译器；然后，用DSL声明式地编写实体描述文件，去描述实体的属性列表，属性的类型、取值范围，属性所支持的操作，属性之间的关系和约束条件等；最后，通过这个实体描述文件自动生成后端的实体类和前端管理页面。采用LOP，不论前后端采用何种技术，Java也好，C#也好，JSP也好，ASP.NET也好，都可以自动生成它们的代码。采用LOP的工作量和质量都集中在DSL的设计和编译器的开发，与实体的数量无关，也就是说，越是庞大的系统，实体类越多越是能体现LOP的优势。
<p>通过上面两个小例子我们可以感受到，LOP是一种面向领域的，高度声明式的编程方式，它的抽象维度与领域模型的维度完全一致。LOP能让程序员从复杂的实现细节中解脱出来，把关注点集中在问题的本质上，从而提高编程的效率和质量。
<p>接下来的问题是如果需要为某领域设计DSL，我们是应该发明一门类似SQL这样的专用DSL呢，还是用XML或S表达式去定义DSL呢？它们各有何优缺点呢？
<p>我认为采用XML或S表达式定义DSL的优点主要有：1) SQL、make file、CSS等专用DSL都只能面向各自的领域，而一个实际的领域问题通常是跨越多个领域的，有时我们需要将不同领域融合在一起，但是由于普通语言的刚性，多语言融合通常会是一件非常困难的事情，而XML和S表达式语法结构的单一性和“代码及数据”的特点使得跨领域融合毫无障碍。2) 在为DSL开发编译器或解释器的方面，二者难度不同。对XML和S表达式定义的DSL进行语法分析非常简单，相比之下，对SQL这样的专用DSL进行语法分析，虽然可以借助Lex、Yacc、ANTLR等代码生成工具，但总的来讲复杂度还是要明显高一些。
<p>当然，XML和S表达式的优点也正好是其缺点，由于XML和S表达式的语法形式是固定的，不能像专用DSL那样自由地设计语法。所以，一般来讲专用DSL的语法显得更加简洁。换句话说，XML和Lisp其实是在语法和语义间做了一个交换，用语法的限制换来了语义的灵活。
<h5>Lisp之器</h5>
<p>接下来我们继续探讨DSL的解释执行问题。DSL代码的解释执行一般分为3种典型的方式：1) 通过专门的解释器解释执行；2) 编译生成其他语言的代码，再通过其他语言的解释器解释执行(或编译运行)；3) 自解释。比如，第1类的代表是SQL，上一节举的两个例子都属于第2类，而第3类自解释正是Lisp的特色。
<p>为了理解自解释，我们可以先从内部DSL的解释执行说起。内部DSL是指嵌入在宿主语言中的DSL，比如，Google Test单元测试框架定义了一套基于流畅接口(Fluent Interface)的C++单元测试DSL。从语义构造的角度看，内部DSL直接借用宿主语言的语法定义了自己的领域语义，是一种语法和语义解耦；从解释执行的角度看，内部DSL是随宿主语言的解释器而自动解释的，不需要像外部DSL一样开发专门的解释器，因而实现的代价很低。当然，并不是说设计内部DSL不用关心任何的解释实现，实际上，还是需要熟悉宿主语言的特性，并利用该特性使得DSL能随着宿主语言的解释器得到解释执行。
<p>Lisp拥有强大的自解释特性，这得益于独一无二的<strong>Lisp之器：宏 (macro)</strong>。宏使得Lisp编写的DSL可以被Lisp解释器直接解释执行，这在原理上与内部DSL是相通的，只是内部DSL一般是利用宿主语言的链式调用等特性，通常形式简陋，功能有限，而Lisp的宏则要强大和灵活得多。
<p>C语言中也有宏的概念，不过Lisp的宏与C语言的宏完全不同，C语言的宏是简单的字符串替换。比如，下面的宏定义：<pre>#define square(x) (x*x)
</pre>
<p>square(1+1)的期望结果是4，而实际上它会被替换成(1+1*1+1)，结果是3。这个例子说明，C语言的宏只在预编译阶段进行简单的字符串替换，对程序语法结构缺乏理解，非常脆弱。Lisp的宏不是简单的字符串替换，而是一套完整的代码生成系统，它是在语法解析的基础上把Lisp代码从一种形式转换为另一种形式，本质上起到了普通语言编译器的作用。不同的是，普通编译器是把一种语言的代码转换为另一种语言的代码，比如，Java编译器把Java代码转换成Java字节码；而Lisp宏的输入和输出都是S表达式，它本质上是把一种DSL转换为另一种DSL。下面的例子是宏的一个典型用法。
<p>例3：假设Lisp解释器已经具备解释执行面向过程DSL的能力，需要实现类似ant的自动化构建工具。
<p>我们可以基于宏构建一门类ant的DSL，宏的作用是把类ant DSL通过宏展开变成面向过程的DSL，最后被Lisp解释器所解释执行。这样用Lisp编写的ant DSL就不需要被编译为其他语言，也不需要像XML的ant一样依赖于专门的解释器了。
<p>当然，和开发专门的解释器/编译器相比，Lisp的宏也并非没有缺点，宏难以理解，开发和调试更加困难。到底是开发专门的解释器/编译器还是直接采用宏应该视具体情况而定。
<h5>总结</h5>
<p>Lisp采用单一的S表达式语法表达不同的语义，实现了语法和语义解耦。这使得Lisp具有强大的语义构造能力，擅长于构造DSL实现面向语言编程，而宏使得Lisp具有自解释能力，让不同DSL之间的转换游刃有余。进入Lisp的世界应当从理解面向语言编程入门，这是Lisp之道，而函数式编程和宏皆为Lisp之器，以道驭器方为正途。
<h5>后记</h5>
<p>本文是我学习Lisp的一个总结，也是写给有兴趣学习Lisp的程序员的入门资料。必须说明，我还是一个标准的Lisp初学者，几乎没有写过像样的Lisp程序，文中的错误和不足在所难免，希望读者批评指正，感谢！
<h5>参考</h5>
<p><a href="http://www.paulgraham.com/rootsoflisp.html">The Roots of Lisp</a>
<p><a href="http://www.defmacro.org/ramblings/lisp.html">The Nature of Lisp</a>
<p><a href="http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.html">Why Lisp macros are cool, a Perl perspective</a>
<p><a href="http://en.wikipedia.org/wiki/Language-oriented_programming">Wikipedia: Language-oriented programming</a>
<p><a href="http://book.douban.com/subject/6859720/">《实用Common Lisp编程》</a>
<p><a href="http://book.douban.com/subject/4031906/">《冒号课堂 – 编程范式与OOP思想》</a></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/178505.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2012-06-12 12:38 <a href="http://www.cppblog.com/sunicdavy/archive/2012/06/12/178505.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows下TortoiseHg合并代码导致FlashDevelop打开乱码的处理方法</title><link>http://www.cppblog.com/sunicdavy/archive/2012/05/12/174629.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Sat, 12 May 2012 02:17:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2012/05/12/174629.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/174629.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2012/05/12/174629.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/174629.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/174629.html</trackback:ping><description><![CDATA[<p>最近团队已经全面弃用SVN全面转移到HG(Mercurial)分布式代码管理</p> <p>Visual Studio系编辑工具由于质量过硬, 兼容性超强,因此使用HG一直没有出现过问题</p> <p>但是第三方开发的FlashDevelop对UNICODE兼容性不好, 出现了很多乱码问题, 特别是在HG合并代码后, 代码中的中文在FlashDevelop中的乱码现象更是严重. 经过验证, 同样代码在FlashBuilder中没有问题. 因此可以推断是FlashDevelop兼容性问题</p> <p>为解决此问题, 需要调整HG的配置, 这里以Windows环境下的TortoiseHg为例</p> <p>解决方案如下:</p> <p>kdiff3是TortoiseHg的默认合并工具, 默认安装路径在c:\Program Files\TortoiseHg\kdiff3.exe, 找到并运行</p> <p>在菜单中找到Settings-&gt;Configure KDiff3...</p> <p>在Regional Settings选项卡中选择Unicode, 8 bit(UTF-8) 然后取消勾选右边的Auto Detect Unicode</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/FlashDevelopHG_8E7A/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/FlashDevelopHG_8E7A/image_thumb.png" width="625" height="273"></a></p> <p>注意, 如果需要混合开发UTF8保存的源码和UNICODE保存的源码, 需要准备两套合并方案, 可以选择兼容性比较好的BeyondCompare</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/174629.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2012-05-12 10:17 <a href="http://www.cppblog.com/sunicdavy/archive/2012/05/12/174629.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于HG版本管理软件的服务器/客户端数据版本发布流程</title><link>http://www.cppblog.com/sunicdavy/archive/2012/04/26/172798.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 26 Apr 2012 03:11:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2012/04/26/172798.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/172798.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2012/04/26/172798.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/172798.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/172798.html</trackback:ping><description><![CDATA[<h1><font face="Lucida Console">传统发布现状</font></h1>
<p><font face="Lucida Console">传统的服务器/客户端版本发布流程都需要经历以下流程:</font></p>
<p><font face="Lucida Console">1. 获取代码</font></p>
<p><font face="Lucida Console">2. 编译代码</font></p>
<p><font face="Lucida Console">3. 将配置,二进制文件, 资源打包</font></p>
<p><font face="Lucida Console">4. 挂接远程服务器磁盘拷贝打包文件</font></p>
<p><font face="Lucida Console">5. 远程操作解压打包文件</font></p>
<p><font face="Lucida Console">6. 修改设置,指向最新版本</font></p>
<p><font face="Lucida Console">7. 重启服务器</font></p>
<p><font face="Lucida Console">此流程繁琐,重复且无聊, 同时, 由于网络带宽,网速等约束, 每次若使用完整包发布,传输起来非常吃力</font></p>
<p><font face="Lucida Console">本文讨论的外网服务器由于安全性要求,禁止root登录,只能用普通帐号登录或传输后, 提权为root继续进行以上操作, 因此rsync的使用受到严重限制</font></p>
<p><font face="Lucida Console">即便使用Windows下的同步软件, 也几乎不可能.</font></p>
<h1><font face="Lucida Console">HG特性及优势</font></h1>
<p><font face="Lucida Console">HG作为一个优秀,小巧的跨平台代码管理软件的特性,正好能解决以上问题, 主要特性:</font></p>
<p><font face="Lucida Console">1. 安装简便, 可以使用代码直接安装</font></p>
<p><font face="Lucida Console">2. 利用本地映射版本可以对新版本做差异比较</font></p>
<p><font face="Lucida Console">3. 增量包传输, 100%同步, 本地文件删除后, 远程文件也会同步删除</font></p>
<p><font face="Lucida Console">4. 传输压缩</font></p>
<p><font face="Lucida Console">5. 增量包可以打包为patch进行离线更新</font></p>
<p><font face="Lucida Console">6. 可以恢复到任意版本, 提交版本有据可查</font></p>
<p><font face="Lucida Console"></font>&nbsp;</p>
<p><strong><font face="Lucida Console">以下部署系统以CentOS为基础, 其他系统类似</font></strong></p>
<p><strong><font face="Lucida Console">本文来自战魂小筑的博客<a href="http://www.cppblog.com/sunicdavy">http://www.cppblog.com/sunicdavy</a> 转载请注明来源</font></strong></p>
<h1><font face="Lucida Console">为远程服务器安装HG </font></h1>
<h2><font face="Lucida Console">安装依赖库</font></h2>
<p><font face="Lucida Console">yum install python-devel</font> </p>
<h2><font face="Lucida Console">获取HG源码</font></h2>
<p><font face="Lucida Console">wget </font><a href="http://mercurial.selenic.com/release/mercurial-2.1.tar.gz"><font face="Lucida Console">http://mercurial.selenic.com/release/mercurial-2.1.tar.gz</font></a> </p>
<p><font face="Lucida Console">tar zxvf ./mercurial-2.1.tar.gz</font> </p>
<h2><font face="Lucida Console">编译安装</font></h2>
<p><font face="Lucida Console">make all</font> </p>
<p><font face="Lucida Console">make install</font> </p>
<p><font face="Lucida Console">hg debuginstall</font> </p>
<p><font face="Lucida Console"></font>&nbsp; </p>
<h1><font face="Lucida Console">使用HG同步数据</font></h1>
<h2><font face="Lucida Console">创建仓库</font></h2>
<p><font face="Lucida Console">找到你需要同步的目录,进入目录</font></p>
<p><font face="Lucida Console">执行</font></p>
<p><font face="Lucida Console">hg init</font></p>
<p><font face="Lucida Console">vi .hg/hgrc</font></p>
<p><font face="Lucida Console">添加以下内容,让这个仓库支持外部push</font></p>
<p><font face="Lucida Console">[ui]</font></p>
<p><font face="Lucida Console">username=<font color="#ff0000">服务器提交后看到的用户名</font></font></p>
<p><font face="Lucida Console">[web]<br /></font></p>
<p><div>push_ssl = false</div><font face="Lucida Console">allow_push=*<br /></font></p>
<h2><font face="Lucida Console">同步</font></h2>
<p><font face="Lucida Console">vi /etc/sysconfig/iptables</font></p>
<p><font face="Lucida Console">添加HG服务的8000端口</font></p>
<p><font face="Lucida Console">-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8000 -j ACCEPT</font></p>
<p><font face="Lucida Console">开启仓库同步服务</font></p>
<p><font face="Lucida Console">hg serve</font></p>
<p><font face="Lucida Console">本地机器同样找到文件夹,创建仓库</font></p>
<p><font face="Lucida Console">hg init</font></p>
<p><font face="Lucida Console">以后每次需要同步时,使用命令,或者乌龟HG的界面工具拉取服务器数据即可</font></p>
<p><font face="Lucida Console">hg pull http://服务器地址:8000</font></p>
<p><font face="Lucida Console"></font>&nbsp;</p>
<p><font face="Lucida Console">版本提交方法与HG日常使用类似, 这里不再阐述</font></p>
<h1><font face="Lucida Console">离线更新</font></h1>
<p>对于某些服务器深处防火墙或者安全登录后方,不能直接开启8000端口的情况</p>
<p>可以使用hg导出一个patch, 传输到远程服务器, 使用hg import PATCH 即可</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/172798.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2012-04-26 11:11 <a href="http://www.cppblog.com/sunicdavy/archive/2012/04/26/172798.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux下使用CodeLite设置工作路径gdb出错的解决方法</title><link>http://www.cppblog.com/sunicdavy/archive/2012/03/30/169535.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 30 Mar 2012 08:07:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2012/03/30/169535.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/169535.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2012/03/30/169535.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/169535.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/169535.html</trackback:ping><description><![CDATA[<p>CodeLite极力的模仿Visual Studio的界面及表现形式. 但是在有些配置项上却存在着操作不同, 看图说话:</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/LinuxCodeLite_E0CD/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/LinuxCodeLite_E0CD/image_thumb.png" width="763" height="183"></a></p> <p>这是项目中的工程配置设定项中的调试器参数设置. 图中将Program启动程序项设定为相对路径, 而Working Folder工作目录项设为绝对路径.</p> <p>这样的设定无法启动调试器, gdb将报错, 无法找到调试程序:</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/LinuxCodeLite_E0CD/image_4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/LinuxCodeLite_E0CD/image_thumb_1.png" width="400" height="155"></a></p> <p>研究了一下, 发现设定项里引导你使用浏览目录对话框进行选择, 尝试一下, 将Program改为绝对路径</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/LinuxCodeLite_E0CD/image_6.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/LinuxCodeLite_E0CD/image_thumb_2.png" width="759" height="107"></a></p> <p>F5开始调试, 不报错, main中使用getcwd获取当前路径验证, 设置正确, 问题解决</p> <p>&nbsp;</p> <p>分析: CodeLite应该只是将两个参数简单的传给了gdb, 但是gdb并不知道工程相对路径,因此报错. 这对于CodeLite开发者来说,理解是正确的, 程序员思想.</p> <p>但是对于产品来说是失败的</p> <p>VisualStudio的调试器与IDE结合紧密, 因此以产品思想开发程序, 就能避免这种类似的问题</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/169535.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2012-03-30 16:07 <a href="http://www.cppblog.com/sunicdavy/archive/2012/03/30/169535.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>让VC调试器正确显示UTF-8字符串</title><link>http://www.cppblog.com/sunicdavy/archive/2012/02/14/165566.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 14 Feb 2012 07:21:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2012/02/14/165566.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/165566.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2012/02/14/165566.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/165566.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/165566.html</trackback:ping><description><![CDATA[<p>默认的, VC调试器只能正常显示ANSI字符串及UNICODE字符串, 而UTF-8字符串及其他格式则无法显示</p> <p>这里无需编写插件及修改配置文件,只需要将要显示的字符串拉到Watch中,并在变量后面添加,s8即可显示</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/165611ed03f8_D62F/image_4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/165611ed03f8_D62F/image_thumb_1.png" width="233" height="42"></a> --&gt; <a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/165611ed03f8_D62F/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/165611ed03f8_D62F/image_thumb.png" width="173" height="51"></a></p> <p>同样类型的功能也应该很熟悉</p> <p>,数字&nbsp; 将变量拆分为数组显示, 数字是要显示多少位, 此法对const char*这类原始字符串非常有用</p> <p>,x 16进制查看</p> <p>,hr&nbsp; 查看Windows HRESULT解释</p> <p>,wm Windows消息,例如0x0010, wm 显示 WM_CLOSE</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/165566.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2012-02-14 15:21 <a href="http://www.cppblog.com/sunicdavy/archive/2012/02/14/165566.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转自CSDN]三好学生Chris Lattner的LLVM编译工具链</title><link>http://www.cppblog.com/sunicdavy/archive/2011/12/31/163277.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Sat, 31 Dec 2011 08:51:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2011/12/31/163277.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/163277.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2011/12/31/163277.html#Feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/163277.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/163277.html</trackback:ping><description><![CDATA[<p>原文链接: <a href="http://www.programmer.com.cn/9436/">http://www.programmer.com.cn/9436/</a></p> <p>作者: 王越</p> <p>&nbsp;</p> <p><strong>2011年12月3日，LLVM 3.0正式版发布，完整支持所有ISO C++标准和大部分C++ 0x的新特性， 这对于一个短短几年的全新项目来说非常不易。</strong></p> <p><strong>开发者的惊愕</strong></p> <p>在2011年WWDC（苹果全球开发者大会）的一场与Objective-C相关的讲座上，开发者的人生观被颠覆了。</p> <p>作为一个开发者，管理好自己程序所使用的内存是天经地义的事，好比人们在溜狗时必须清理狗的排泄物一样（美国随处可见“Clean up after your dogs”的标志）。在本科阶段上C语言的课程时，教授们会向学生反复强调：如果使用malloc函数申请了一块内存，使用完后必须再使用free函数把申请的内存还给系统——如果不还，会造成“内存泄漏”的结果。这对于Hello World可能还不算严重，但对于庞大的程序或是长时间运行的服务器程序，泄内存是致命的。如果没记住，自己还清理了两次，造成的结果则严重得多——<a href="https://blog.delphij.net/2009/10/free.html">直接导致程序崩溃</a>。</p> <p>Objective-C有类似malloc/free的对子，叫alloc/dealloc，这种原始的方式如同管理C内存一样困难。所以Objective-C中的内存管理又增加了“引用计数”的方法，也就是如果一个物件被别的物件引用一次，则引用计数加一；如果不再被该物件引用，则引用计数减一；当引用计数减至零时，则系统自动清掉该物件所占的内存。具体来说，如果我们有一个字符串，当建立时，需要使用alloc方法来申请内存，引用计数则变成了一；然后被其他物件引用时，需要用retain方法去增加它的引用计数，变成二。当它和刚才引用的物件脱离关联时，需使release方法减少引用计数，又变回了一；最后，使用完这个字符串时，再用release方法减少其引用计数，这时，运行库发现其引用计数变为零了，则回收走它的内存。这是<a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH">手动的方式</a>。</p> <p>这种方式自然很麻烦，所以又设计出一种叫做autorelease的机制（不是类似Java的自动垃圾回收）。在Objective-C中，设计了一个叫做NSAutoReleasePool的池，当开发者需要完成一个任务时（比如每开启一个线程，或者开始一个函数），可以手动创立一个这样的池子， 然后通过显式申明把物件扔进自动回收池中。NSAutoReleasePool内有一个数组来保存声明为autorelease的所有对象。如果一个对象声明为autorelease，则会自动加到池子里。如果完成了一个任务（结束线程了，或者退出那个函数），则开发者需对这个池子发送一个drain消息。这时，NSAutoReleasePool会对池子中所有的物件发送release消息，把它们的引用计数都减一 ——这就好比游泳池关门时通知所有客人都“滚蛋”一样。所以开发者无需显式声明release，所有的物件也会在池子清空时自动呼叫release函数，如果引用计数变成零了，系统才回收那块内存。所以这是个<a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI">半自动、半手动的方式</a>。</p> <p>Objective-C的这种方式虽然比起C来进了一大步，我刚才花了几分钟就和读者讲明白了。只要遵守上面这两个简单的规则，就可以保证不犯任何错误。但这和后来的Java自动垃圾回收相比则是非常繁琐的，哪怕是再熟练的开发者，一不小心就会弄错。而且，哪怕很简单的代码，比如物件的getter/setter函数，都需要用户写上一堆的代码来管理接收来的物件的内存。</p> <p>经典教材《Cocoa Programming for Mac OS X》用了整整一章节的篇幅，来讲解Objective-C中内存管理相关的内容，但初学者们看得还是一头雾水。所以，在2007年10.5发布时，Objective-C做出了有史以来最大的更新，最大的亮点是它的运行库libobjc 2.0正式支持自动垃圾回收，也就是由运行库在运行时随时侦测哪些物件需要被释放。听上去很不错，可惜使用这个技术的项目却少之又少。原因很简单，使用这个特性，会有很大的性能损失，使Objective-C的内存管理效率低得和Java一样，而且一旦有一个模块启用了这个特性，这个进程中所有的地方都要启用这个特性——因此如果你写了一个使用垃圾回收的库，那所有引用你库的程序就都得被迫使用垃圾回收。所以Apple自己也不使用这项技术，大量的第三方库也不使用它。</p> <p>这个问题随Apple在移动市场的一炮走红而变得更加严峻。不过这次，Apple和与会的开发者讲，他们找到了一个解决问题的终极方法，这个方法把从世界各地专程赶来聆听圣谕的开发者惊得目瞪口呆——你不用写任何内存管理代码，也不需要使用自动垃圾回收。因为我们的编译器已经学会了上面所介绍的内存管理规则，会自动在编译程序时把这些代码插进去。</p> <p>这个编译器，一直是Apple公开的秘密——LLVM。说它公开，是因为它自始至终都是一个开源项目；而秘密，则是因为它从来没公开在WWDC的Keynote演讲上亮相过 。</p> <p>一直关注这系列连载的读者一定还记得，在第二篇《Linus Torvalds的短视》介绍Apple和GPL社区的不合时，提到过“自以为是但代码又写得差的开源项目，Apple事后也遇到不少，比如GCC编译器项目组。虽然大把钞票扔进去，在先期能够解决一些问题，但时间长了这群人总和Apple过不去，并以自己在开源世界的地位恫吓之，最终Apple由于受不了这些项目组的态度、协议、代码质量，觉得还不如自己造轮子来得方便。”LLVM则是Apple造的这个轮子，它的目的是完全替代掉GCC那条编译链。它的主要作者，则是现在就职于Apple的Chris Lattner。</p> <p><strong>编译器高材生Chris Lattner</strong></p> <p>2000年，本科毕业的Chris Lattner像中国多数大学生一样，按部就班地考了GRE，最终前往UIUC（伊利诺伊大学厄巴纳香槟分校），开始了艰苦读计算机硕士和博士的生涯。在这阶段，<a href="http://photos.nondot.org/">他不仅周游美国各大景点</a>，更是努力学习科学文化知识，翻烂了“龙书”（《Compilers: Principles, Techniques, and Tools》），<a href="http://nondot.org/sabre/Resume.html">成了GPA牛人</a>【注：最终学分积4.0满分】，以及不断地研究探索关于编译器的未知领域，发表了一篇又一篇的论文，是中国传统观念里的“三好学生”。他的<a href="http://www.programmer.com.cn/9436/%E6%B3%A8%EF%BC%9ALLVM:%20An%20Infrastructure%20for%20Multi-Stage%20Optimization%EF%BC%8C%20http://llvm.org/pubs/2002-12-LattnerMSThesis.html">硕士毕业论文提出了一套完整的在编译时、链接时、运行时甚至是在闲置时优化程序的编译思想</a>，直接奠定了LLVM的基础。 <br>LLVM在他念博士时更加成熟，使用GCC作为前端来对用户程序进行语义分析产生IF（Intermidiate Format），然后LLVM使用分析结果完成代码优化和生成。这项研究让他在2005年毕业时，成为小有名气的编译器专家，他也因此早早地被Apple相中，成为其编译器项目的骨干。</p> <p>Apple相中Chris Lattner主要是看中LLVM能摆脱GCC束缚。Apple（包括中后期的NeXT） 一直使用GCC作为官方的编译器。GCC作为开源世界的编译器标准一直做得不错，但Apple对编译工具会提出更高的要求。</p> <p>一方面，是Apple对Objective-C语言（甚至后来对C语言）新增很多特性，但GCC开发者并不买Apple的帐——不给实现，因此索性后来两者分成两条分支分别开发，这也造成Apple的编译器版本远落后于GCC的官方版本。另一方面，GCC的代码耦合度太高，不好独立，而且<a href="http://www.thejemreport.com/more-on-openbsds-new-compiler/">越是后期的版本，代码质量越差</a>，但Apple想做的很多功能（比如更好的IDE支持）需要模块化的方式来调用GCC，但GCC一直不给做。甚至最近，《<a href="https://blog.delphij.net/2009/01/gcc.html">GCC运行环境豁免条款 （英文版）</a>》从根本上限制了LLVM-GCC的开发。 所以，这种不和让Apple一直在寻找一个高效的、模块化的、协议更放松的开源替代品，Chris Lattner的LLVM显然是一个很棒的选择。</p> <p>刚进入Apple，Chris Lattner就大展身手：首先在OpenGL小组做代码优化，把LLVM运行时的编译架在OpenGL栈上，这样OpenGL栈能够产出更高效率的图形代码。如果显卡足够高级，这些代码会直接扔入GPU执行。但对于一些不支持全部OpenGL特性的显卡（比如当时的Intel GMA卡），<a href="http://lists.cs.uiuc.edu/pipermail/llvmdev/2006-August/006492.html">LLVM则能够把这些指令优化成高效的CPU指令，使程序依然能够正常运行</a>。这个强大的OpenGL实现被用在了后来发布的Mac OS X 10.5上。同时，LLVM的链接优化被直接加入到Apple的代码链接器上，而LLVM-GCC也被同步到使用GCC4代码。</p> <p>LLVM真正的发迹，则得等到Mac OS X 10.6 Snow Leopard登上舞台。可以说， Snow Leopard的新功能，完全得益于LLVM的技术。而这一个版本，也是将LLVM推向真正成熟的重大机遇。</p> <p>关于Snow Leopard的三项主推技术（64位支持、OpenCL，以及Grand Central Dispatch）的细节，我们会在下一次有整整一期篇幅仔细讨论，这次只是点到为止——我们告诉读者，这些技术，不但需要语言层面的支持（比如<a href="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html">Grand Centrual Dispatch所用到的“代码块”语法</a>， 这被很多人看作是带lambda的C），也需要底层代码生成和优化（比如OpenCL是在运行时编译为GPU或CPU代码并发执行的）。而这些需求得以实现，归功于LLVM自身的新前端——Clang。</p> <p><strong>优异的答卷——Clang</strong></p> <p>前文提到，Apple吸收Chris Lattner的目的要比改进GCC代码优化宏大得多——GCC系统庞大而笨重，而Apple大量使用的Objective-C在GCC中优先级很低。此外GCC作为一个纯粹的编译系统，与IDE配合得很差。加之许可证方面的要求，Apple无法使用LLVM 继续改进GCC的代码质量。于是，Apple决定从零开始写 C、C++、Objective-C语言的前端 Clang，完全替代掉GCC。</p> <p>正像名字所写的那样，Clang只支持C，C++和Objective-C三种C家族语言。<a href="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2007-July/000000.html">2007年开始开发</a>，C编译器最早完成，而由于Objective-C相对简单，只是C语言的一个简单扩展，很多情况下甚至可以等价地改写为C语言对Objective-C运行库的函数调用，因此在2009年时，已经完全可以用于生产环境。C++的支持也热火朝天地进行着。</p> <p>Clang的加入代表着LLVM真正走向成熟和全能，Chris Lattner以影响他最大的<a href="http://en.wikipedia.org/wiki/Dragon_Book_(computer_science)">“龙书”封面</a>【注：见http://en.wikipedia.org/wiki/Dragon_Book_(computer_science)】为灵感，为项目选定了图标——<a href="http://llvm.org/img/DragonMedium.png">一条张牙舞爪的飞龙</a>。</p> <p>Clang一个重要的特性是编译快速，占内存少，而代码质量还比GCC来得高。测试结果表明Clang编译Objective-C代码时速度为GCC的3倍【注：http://llvm.org/pubs/2007-07-25-LLVM-2.0-and-Beyond.pdf】，而语法树（AST）内存占用则为被编译源码的1.3倍，而<a href="http://llvm.org/devmtg/2007-05/09-Naroff-CFE.pdf">GCC则可以轻易地可以超过10倍</a>。Clang不但编译代码快，对于用户犯下的错误，也能够更准确地给出建议。使用过GCC的读者应该熟悉，GCC给出的错误提示基本都不是给人看的。</p> <p>比如最简单的：</p> <p>struct foo { int x; } <br>typedef int bar;</p> <p>如果使用GCC编译，它将告诉你： <br>t.c:3: error: two or more data types in declaration specifiers</p> <p>但是Clang给出的出错提示则显得人性化得多： <br>t.c:1:22: error: expected ‘;’ after struct</p> <p>甚至，Clang可以根据语境，像拼写检查程序一样地告诉你可能的替代方案。 <br>比如这个程序：</p> <p>#include &lt;inttypes.h&gt; <br>int64 x;</p> <p>GCC一样给出乱码似的出错提示：</p> <p>t.c:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘x’</p> <p>而优雅的Clang则用彩色的提示告诉你是不是拼错了，并给出可能的变量名：</p> <p>t.c:2:1: error: unknown type name ‘int64′; did you mean ‘int64_t’? <br>int64 x;^~~~~int64_t</p> <p>更多的例子可以参考http://blog.llvm.org/2010/04/amazing-feats-of-clang-error-recovery.html。 而同时又因为Clang是高度模块化的一个前端，很容易实现代码的高度重用。所以比如Xcode 4.0的集成编程环境就使用Clang的模块来实现代码的自动加亮、代码出错的提示和自动的代码补全。开发者使用Xcode 4.0以后的版本，可以极大地提高编程效率，尽可能地降低编译错误的发生率。</p> <p>支持C++也是Clang的一项重要使命。C++是一门非常复杂的语言，大多编译器（如GCC、MSVC）用了十多年甚至二十多年来完善对C++的支持，但效果依然不很理想。Clang的C++支持却一直如火如荼地展开着。2010年2月4日，Clang已经成熟到能自举（即使用Clang编译Clang，到我发稿时，<a href="http://clang.llvm.org/cxx_status.html">LLVM 3.0发布已完整支持所有ISO C++标准，以及大部分C++ 0x的新特性</a>。</p> <p>这对于一个短短几年的全新项目来说是非常不易的。得益于本身健壮的架构和Apple的大力支持，Clang越来越全能，从<a href="http://lists.freebsd.org/pipermail/freebsd-current/2009-February/003743.html">FreeBSD</a>【注：http://lists.freebsd.org/pipermail/freebsd-current/2009-February/003743.html】 到<a href="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2010-October/011711.html">Linux Kernel</a>【注：http://lists.cs.uiuc.edu/pipermail/cfe-dev/2010-October/011711.html】， 从<a href="http://blog.llvm.org/2010/05/clang-builds-boost.html">Boost</a>【注：http://blog.llvm.org/2010/05/clang-builds-boost.html】 到<a href="http://weblogs.java.net/blog/simonis/archive/2011/02/10/compiling-hotspot-vm-clang">Java虚拟机</a>， Clang支持的项目越来越多。</p> <p>Apple的Mac OS X以及iOS也成了Clang和LLVM的主要试验场——10.6时代，很多需要高效运行的程序比如OpenSSL和Hotspot就由LLVM-GCC编译来加速的。而10.6时代的Xcode 3.2诸多图形界面开发程序如Xcode、Interface Builder等，皆由Clang编译。到了Mac OS X 10.7，整个系统的的代码都由Clang或LLVM-GCC编译【注：http://llvm.org/Users.html】。</p> <p><strong>LLVM周边工具</strong></p> <p>由于受到Clang项目的威胁，GCC也不得不软下来，让自己变得稍微模块化一些，推出<a href="http://gcc.gnu.org/wiki/plugins">插件的支持</a>，而LLVM项目则顺水推舟，索性废掉了出道时就一直作为看家本领的LLVM-GCC，改为一个<a href="http://dragonegg.llvm.org/">GCC的插件DragonEgg</a>。 Apple也于Xcode 4.2彻底抛弃了GCC工具链。</p> <p>而Clang的一个重要衍生项目，则是<a href="http://clang-analyzer.llvm.org/images/analyzer_html.png">静态分析工具</a>，能够通过自动分折程序的逻辑，在编译时就找出程序可能的bug。在Mac OS X 10.6时，静态分析被集成进Xcode 3.2，帮助用户查找自己犯下的错误。其中一个功能，就是告诉用户内存管理的Bug，比如alloc了一个物件却忘记使用<a href="http://clang-analyzer.llvm.org/images/analyzer_xcode.png">release回收</a>。这已经是一项很可怕的技术，而Apple自己一定使用它来发现并改正Mac OS X整个系统各层面的问题。但许多开发者还不满足——既然你能发现我漏写了release，你为什么不能帮我自动加上呢？于是ARC被<a href="http://www.programmer.com.cn/9436/Automatic%20Reference%20Counting%20http://clang.llvm.org/docs/AutomaticReferenceCounting.html">集成进Clang</a>，发生了文章开头开发者们的惊愕——从来没有人觉得这件事是可以做成的。</p> <p>除LLVM核心和Clang以外，LLVM还包括一些重要的子项目，比如一个<a href="http://lldb.llvm.org/">原生支持调试多线程程序的调试器LLDB</a>，和一个<a href="http://libcxx.llvm.org/">C++的标准库libstdc++</a>，这些项目由于是从零重写的，因此要比先前的很多项目站得更高，比如先前GNU、Apache、STLport等C++标准库在设计时，C++0x标准还未公布，所以大多不支持这些新标准或者需要通过一些肮脏的改动才能支持，而libstdc++则原生支持C++0x。而且在现代架构上，这些项目能动用多核把事情处理得更好。</p> <p>不单单是Apple，诸多的项目和编程语言都从LLVM里取得了关键性的技术。<a href="http://blog.llvm.org/2010/05/glasgow-haskell-compiler-and-llvm.html">Haskell语言编译器GHC使用LLVM作为后端</a>，实现了高质量的代码编译。很多动态语言实现也使用LLVM作为运行时的编译工具，较著名的有Google的Unladen Swallow【注：<a href="http://code.google.com/p/unladen-swallow/">Python实现，后夭折</a>】、PyPy【注：<a href="http://codespeak.net/pypy/dist/pypy/doc/index.html">Python实现</a>】，以及MacRuby【注：<a href="http://www.programmer.com.cn/9436/macruby.org/">Ruby实现</a>】。<a href="http://programmingzen.com/2009/03/29/why-macruby-matters/">例如 MacRuby 后端改为LLVM后，速度不但有了显著的提高</a>，更是支持Grand Central Dispatch来实现高度的并行运行。由于LLVM高度的模块化，很方便重用其中的组件来作为一个实现的重要组成部分，因此类似的项目会越来越多。</p> <p>LLVM的成熟也给其他痛恨GCC的开发项目出了一口恶气。其中最重要的，恐怕是以FreeBSD为代表的BSD社区。BSD社区和Apple的联系一向很紧密，而且由于代码相似，很多Apple的技术如Grand Central Dispatch也是最早移植到FreeBSD上。<a href="http://en.wikipedia.org/wiki/Portable_C_Compiler">BSD社区很早就在找GCC的替代品</a>，无奈大多都很差（如Portable C Compiler产生的代码质量和gcc不能同日而语）。</p> <p>一方面是因为不满意GCC的代码品质【注：BSD代码整体要比GNU的高一些，GNU代码永无休止地出现各种严重的<a href="https://blog.delphij.net/2007/01/gpl-gzip1.html">安全问题</a>】，更重要的是协议问题。BSD开发者有洁癖的居多，大多都不喜欢GPL代码，尤其是<a href="http://www.freebsdfoundation.org/press/2007Aug-newsletter.shtml">GPL协议第三版发布时，和FreeBSD的协议甚至是冲突的</a>。这也正是为什么FreeBSD中包含的GNU的C++运行库还是2007年以GPLv2发布的老版本，而不是支持C++0x的但依GPLv3协议发布的新版本。 因此历时两年的开发后，2012年初发布的FreeBSD 9.0中，<a href="http://wiki.freebsd.org/BuildingFreeBSDWithClang">Clang被加入到FreeBSD的基础系统</a>。 但这只是第一步，因为FreeBSD中依然使用GNU的C++ STL 库、C++运行库、GDB调试器、libgcc/libgcc_s编译库都是和编译相关的重要底层技术，先前全被GNU垄断，而现在LLVM子项目lldb、libstdc++、compiler-rt等项目的出现，使BSD社区有机会向GNU说“不”，因此一个把<a href="http://wiki.freebsd.org/GPLinBase">GNU组件移出FreeBSD的计划被构想出来</a>，并完成了很大一部分。编写过《Cocoa Programming Developer’s Handbook》的著名Objective-C牛人David Chisnall也被吸收入FreeBSD开发组完成这个计划的关键部分。 预计在FreeBSD 10发布时，将不再包含GNU代码。</p> <p>LLVM在短短五年内取得的快速发展充分反映了Apple对于产品技术的远见和处理争端的决心和手腕，并一跃成为最领先的开源软件技术。而Chris Lattner在2010年也赢得了他应有的荣誉——Programming Languages Software Award（程序设计语言软件奖）。</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>本站评:</p> <p>&nbsp;&nbsp;&nbsp; 一直对LLVM 及Clang搞的迷迷糊糊的, 这篇文章写的很翔实.</p> <p>&nbsp;&nbsp;&nbsp; 微软在产品及平台上的开放性简直是坑爹. 虽然开发工具上很给力, 但其致命点仍然是封闭</p> <p>&nbsp;&nbsp;&nbsp; 苹果简单,高效, 用户至上的思想在其平台及产品中(AppleScript,LLVM,Clang)体现得淋漓精致. 垃圾回收的改进一路磕磕碰碰,但最终的方案让我们折服.</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/163277.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2011-12-31 16:51 <a href="http://www.cppblog.com/sunicdavy/archive/2011/12/31/163277.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Notepad++挂接ProtoBuffer代码生成器protoc</title><link>http://www.cppblog.com/sunicdavy/archive/2011/12/22/162578.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 22 Dec 2011 03:00:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2011/12/22/162578.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/162578.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2011/12/22/162578.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/162578.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/162578.html</trackback:ping><description><![CDATA[<p>在插件菜单NppExec-&gt;Execute弹出的对话框中输入以下信息</p> <p>"protoc.exe"&nbsp;&nbsp; --cpp_out $(CURRENT_DIRECTORY) --proto_path $(CURRENT_DIRECTORY)&nbsp; $(FULL_CURRENT_PATH)&nbsp; </p> <p>&nbsp;</p> <p>protoc.exe的路径可以自己指定本机的绝对路径</p> <p>编译出的文件将自动放置到proto文件所在目录</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/162578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2011-12-22 11:00 <a href="http://www.cppblog.com/sunicdavy/archive/2011/12/22/162578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跨平台修改代码的解决方法</title><link>http://www.cppblog.com/sunicdavy/archive/2011/12/15/162159.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 15 Dec 2011 03:02:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2011/12/15/162159.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/162159.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2011/12/15/162159.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/162159.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/162159.html</trackback:ping><description><![CDATA[<p>本人使用Windows为主要开发平台, Linux为编译,调试平台 <p>Linux使用类VC的IDE CodeLite <p>设置方法: <p>1. Settings-&gt;Global Editor Preferences-&gt;Misc-&gt;Encoding and Locale <p>2. File font encoding: 选择 WINDOWS-936 <p>3. Locale to use zh_CN: Chinese(Simplified) <p>重启CodeLite, 可有效避免Linux修改了文件,导入Windows变成乱码!</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/162159.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2011-12-15 11:02 <a href="http://www.cppblog.com/sunicdavy/archive/2011/12/15/162159.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC9的预编译头C1859编译错误解决方法</title><link>http://www.cppblog.com/sunicdavy/archive/2011/12/12/161982.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 12 Dec 2011 11:07:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2011/12/12/161982.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/161982.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2011/12/12/161982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/161982.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/161982.html</trackback:ping><description><![CDATA[<p>今天从hg取过代码后编译代码,居然出现了C1859的预编译头破损错误,查过预编译头设置与清空中间文件夹重试,问题依旧. </p> <p>Google后发现解决方法:打补丁</p> <p>问题说明:<a href="http://support.microsoft.com/kb/976656">http://support.microsoft.com/kb/976656</a></p> <p>补丁地址 <a href="http://archive.msdn.microsoft.com/KB976656/Release/ProjectReleases.aspx?ReleaseId=3703">http://archive.msdn.microsoft.com/KB976656/Release/ProjectReleases.aspx?ReleaseId=3703</a></p> <p>&nbsp;</p> <p>考虑部署到vs2010, 但vs2012又要出来了,还是忍忍吧</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/161982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2011-12-12 19:07 <a href="http://www.cppblog.com/sunicdavy/archive/2011/12/12/161982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>