LiteIDE X32.2 发布,Go 语言开发工具

visualfc 发表了文章 • 1 个评论 • 204 次浏览 • 2017-07-19 08:21 • 来自相关话题

Go 语言开发工具 LiteIDE X32.2 正式发布,这个版本解决了编辑器监控外部文件多次修改后监控失效的问题,调试插件启用了保存断点功能,修复了调试测试用例功能,修复了 Dlv 调试进程工作路径问题。

Go 语言开发工具 LiteIDE X32.2 正式发布,这个版本解决了编辑器监控外部文件多次修改后监控失效的问题,调试插件启用了保存断点功能,修复了调试测试用例功能,修复了 Dlv 调试进程工作路径问题。





2017.7.18 Ver X32.2



  • LiteApp

    • fix editor file watcher is invalid for many change


  • GolangEdit

    • fix TODO/BUG/FIXME comment syntax


  • DlvDebugger

    • fix dlv headless process workdir


  • LiteDebug

    • fix debug tests action

    • fix load and save breakpoint for editor


斗鱼弹幕获取

songtianyi 发表了文章 • 3 个评论 • 239 次浏览 • 2017-07-14 23:09 • 来自相关话题

barrage

各平台弹幕协议和开放平台API github

支持列表

barrage


各平台弹幕协议和开放平台API
github


支持列表



  • douyu.com

  • bilibili.com


例子



  • douyu


package main

import (
"fmt"
"github.com/songtianyi/barrage/douyu"
"github.com/songtianyi/rrframework/logs"
)

func chatmsg(msg *douyu.Message) {
level := msg.GetStringField("level")
nn := msg.GetStringField("nn")
txt := msg.GetStringField("txt")
logs.Info(fmt.Sprintf("level(%s) - %s >>> %s", level, nn, txt))
}

func main() {
client, err := douyu.Connect("openbarrage.douyutv.com:8601", nil)
if err != nil {
logs.Error(err)
return
}

client.HandlerRegister.Add("chatmsg", douyu.Handler(chatmsg), "chatmsg")
if err := client.JoinRoom(288016); err != nil {
logs.Error(fmt.Sprintf("Join room fail, %s", err.Error()))
return
}
client.Serve()
}

demo


douyu-barrage-demo

SpaceVim - 终端下最好用的 IDE

SpaceVim 发表了文章 • 4 个评论 • 252 次浏览 • 2017-07-11 09:39 • 来自相关话题

SpaceVim 中文手册

查看全部

SpaceVim 中文手册


Build Status
Version 0.2.0-dev
[MIT License]()
Doc
QQ
Gitter
Facebook


GitHub watchers
GitHub stars
GitHub forks
Twitter Follow


2017-04-29-20 54 49


项 目 主 页: spacevim.org


Github 地址 : SpaceVim GitHub, 欢迎Star或fork。


SpaceVim 是一个社区驱动的模块化 vim/neovim 配置集合,其中包含了多种功能模块,并且针对 neovim 做了功能优化。spacevim 有多种功能模块可供选择,用户只需要选择需要的模块,就可以配置出一个适合自己的开发环境。


使用过程中遇到问题或者有什么功能需求可以在 github 提交 issue,这将更容易被关注和修复。我们也欢迎喜欢 vim/neovim 的用户加入我们的 QQ 群,一起讨论 vim 相关的技巧,点击加入Vim/SpaceVim用户群


以下是近几周的开发汇总:


Throughput Graph


目录
安装
更新
特性
用户配置


安装


Linux 或 Mac 下 SpaceVim的安装非常简单,只需要执行以下命令即可:


curl -sLf https://spacevim.org/install.sh | bash

想要获取更多的自定义的安装方式,请参考:


curl -sLf https://spacevim.org/install.sh | bash -s -- -h

SpaceVim是一种模块化配置,可以运行在vim或者neovim上,关于vim以及neovim的安装,请参考以下链接:


安装neovim


从源码编译vim


windows系统下的安装步骤:


Windows 下 vim 用户只需要将本仓库克隆成用户 HOME 目录下的 vimfiles 即可,打开 CMD 默认的目录默认即为 HOME 目录,只需要执行如下命令即可:


git clone https://github.com/SpaceVim/SpaceVim.git vimfiles

Windows 下 neovim 用户 需要将本仓库克隆成用户 HOME 目录下的 AppData\Local\nvim,想要获取跟多关于 neovim 安装相关的知识,可以访问 neovim 的 wiki, wiki 写的非常详细。打开 CMD 初始目录默认一般即为 HOME 目录,只需要执行如下命令即可:


git clone https://github.com/SpaceVim/SpaceVim.git AppData\Local\nvim

字体


SpaceVim 默认启用了Powerline 字体,默认的的字体文件是:DejaVu Sans Mono, Windows 用户直接下载下来右键安装即可。


vimproc.dll


Windows 下用户如果不方便编译,可以在qq群文件里面下载相应的dll文件放到vimproc
的lib目录,默认是 ~/.cache/vimfiles/repos/github.com/Shougo/vimproc.vim/lib/


特性


优雅的界面


SpaceVim 的默认界包括 tagbar 、vimfiler 、以及 airline 界面,配色主题采用的 gruvbox。


UI


Unite为主的工作平台


Unite 的快捷键前缀是f, 可以通过 g:spacevim_unite_leader 来设定,快捷键无需记忆,SpaceVim 有很好的快捷键辅助机制,如下是 Unite 的快捷键键图:


unite


自动补全


SpaceVim 采用最快补全引擎 deoplete, 该引擎不同与YouCompleteMe的主要一点是支持多源补全,而不单单是语义补全。 而且补全来源拓展非常方便。


细致的tags管理


用户配置


SpaceVim 将从 ~/.SpaceVim.d/init.vim 和当前目录的 ./SpaceVim.d/init.vim 载入配置,并且更新 rtp,用户可以在 ~/.SpaceVim.d/ 和 .SpaceVim.d/ 这两个文件夹下编辑自己的脚本,和 SpaceVim 的配置文件。


示例:


" Here are some basic customizations,
" please refer to the ~/.SpaceVim.d/init.vim
" file for all possible options:
let g:spacevim_default_indent = 3
let g:spacevim_max_column = 80

" Change the default directory where all miscellaneous persistent files go.
" By default it is ~/.cache/vimfiles/.
let g:spacevim_plugin_bundle_dir = '~/.cache/vimfiles/'

" set SpaceVim colorscheme
let g:spacevim_colorscheme = 'jellybeans'

" Set plugin manager, you want to use, default is dein.vim
let g:spacevim_plugin_manager = 'dein' " neobundle or dein or vim-plug

" use space as `<Leader>`
let mapleader = "\<space>"

" Set windows shortcut leader [Window], default is `s`
let g:spacevim_windows_leader = 's'

" Set unite work flow shortcut leader [Unite], default is `f`
let g:spacevim_unite_leader = 'f'

" By default, language specific plugins are not loaded. This can be changed
" with the following, then the plugins for go development will be loaded.
call SpaceVim#layers#load('lang#go')

" loaded ui layer
call SpaceVim#layers#load('ui')

" If there is a particular plugin you don't like, you can define this
" variable to disable them entirely:
let g:spacevim_disabled_plugins=[
\ ['junegunn/fzf.vim'],
\ ]

" If you want to add some custom plugins, use these options:
let g:spacevim_custom_plugins = [
\ ['plasticboy/vim-markdown', {'on_ft' : 'markdown'}],
\ ['wsdjeg/GitHub.vim'],
\ ]

" set the guifont
let g:spacevim_guifont = 'DejaVu\ Sans\ Mono\ for\ Powerline\ 11'

SpaceVim选项

























































选项名称 默认值 描述
g:spacevim_default_indent 2 对齐空格
g:spacevim_enable_guicolors 1 启用/禁用终端使用真色彩
g:spacevim_windows_leader s 窗口管理快捷键前缀
g:spacevim_unite_leader f Unite快捷键前缀
g:spacevim_plugin_bundle_dir ~/.cache/vimfiles 默认插件缓存位置
g:spacevim_realtime_leader_guide 0 启用/禁用实时快捷键提示
g:spacevim_guifont '' 设置SpaceVim字体
g:spacevim_sidebar_width 30 设置边栏宽度,文件树以及语法树
g:spacevim_custom_plugins [] 设置自定义插件

LiteIDE X32.1 发布,Go 语言开发工具

visualfc 发表了文章 • 2 个评论 • 156 次浏览 • 2017-07-11 08:58 • 来自相关话题

Go 语言开发工具 LiteIDE X32.1 正式发布。

新版本修复了 X32 版本的一些错误,优化了环境设置的加载;项目自定义 GOPATH 设置实现了子目录自动继承上级目录设置;Gocode 代码自动完成插件也已支持项目的自定义 GO... 查看全部

Go 语言开发工具 LiteIDE X32.1 正式发布。


新版本修复了 X32 版本的一些错误,优化了环境设置的加载;项目自定义 GOPATH 设置实现了子目录自动继承上级目录设置;Gocode 代码自动完成插件也已支持项目的自定义 GOPATH 设置;Dlv 调试插件启用了服务器模式(dlv headless mode),实现了应用输出和调试信息输出的分离。





更新记录 2017.7.7 Ver X32.1



  • LiteIDE

    • build config custom gopath support inherit parent path's gopath setup


  • GolangCode

    • update gocode lib-path by build config custom gopath


  • LiteEnv

    • optimization check go enviroment


  • LiteBuild

    • build config custom gopath inherit parent path

    • fix BuildAndRun kill old on window

    • fix build config custom gopath action


  • GolangPackage

    • fix load package treeview error


  • DlvDebugger

    • dlv use headless mode

    • fix dlv kill process


对于 Go 中的实用函数我有话说

taowen 发表了文章 • 0 个评论 • 285 次浏览 • 2017-07-09 23:13 • 来自相关话题

目标:让 Go 中支持类似下面这样的函数

func Max(collection ...interface{}) interf... 			查看全部
					

目标:让 Go 中支持类似下面这样的函数


func Max(collection ...interface{}) interface{}

问题:如果用反射实现的话,效率是问题。


解决方案:json.Unmarshal 就是用反射实现的,jsoniter 通过用 unsafe.Pointer 加上缓存的 decoder 实现了6倍的速度提升。所以尝试用同样的技术原理,写一个概念验证的原型 https://github.com/v2pro/wombat


实现的API类似这样


import (
"testing"
"github.com/stretchr/testify/require"
"github.com/v2pro/plz"
)

func Test_max_min(t *testing.T) {
should := require.New(t)
should.Equal(3, plz.Max(1, 3, 2))
should.Equal(1, plz.Min(1, 3, 2))

type User struct {
Score int
}
should.Equal(User{3}, plz.Max(
User{1}, User{3}, User{2},
"Score"))
}

其中的原理是从 interface{} 中提取 unsafe.Pointer。 然后用 Accessor 获得具体的值。这个 Accessor 的概念是和类对应的,而不是和值对应的。也就是相当于 type.GetIntValue(interface{}) 这样的意思。这个在 Java 的反射 API 中是支持的,而 Go 没有提供这样的 API。利用 Accessor 我们可以一次性计算好整个任务,然后缓存起来。这样运行期的成本大概就是虚函数调用的成本。


Accessor 的接口定义


type Accessor interface {
// === static ===
fmt.GoStringer
Kind() Kind
// map
Key() Accessor
// array/map
Elem() Accessor
// struct
NumField() int
Field(index int) StructField
// array/struct
RandomAccessible() bool
New() (interface{}, Accessor)

// === runtime ===
IsNil(ptr unsafe.Pointer) bool
// variant
VariantElem(ptr unsafe.Pointer) (elem unsafe.Pointer, elemAccessor Accessor)
InitVariant(ptr unsafe.Pointer, template Accessor) (elem unsafe.Pointer, elemAccessor Accessor)
// map
MapIndex(ptr unsafe.Pointer, key unsafe.Pointer) (elem unsafe.Pointer) // only when random accessible
SetMapIndex(ptr unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) // only when random accessible
IterateMap(ptr unsafe.Pointer, cb func(key unsafe.Pointer, elem unsafe.Pointer) bool)
FillMap(ptr unsafe.Pointer, cb func(filler MapFiller))
// array/struct
ArrayIndex(ptr unsafe.Pointer, index int) (elem unsafe.Pointer) // only when random accessible
IterateArray(ptr unsafe.Pointer, cb func(index int, elem unsafe.Pointer) bool)
FillArray(ptr unsafe.Pointer, cb func(filler ArrayFiller))
// primitives
Skip(ptr unsafe.Pointer) // when the value is not needed
String(ptr unsafe.Pointer) string
SetString(ptr unsafe.Pointer, val string)
Bool(ptr unsafe.Pointer) bool
SetBool(ptr unsafe.Pointer, val bool)
Int(ptr unsafe.Pointer) int
SetInt(ptr unsafe.Pointer, val int)
Int8(ptr unsafe.Pointer) int8
SetInt8(ptr unsafe.Pointer, val int8)
Int16(ptr unsafe.Pointer) int16
SetInt16(ptr unsafe.Pointer, val int16)
Int32(ptr unsafe.Pointer) int32
SetInt32(ptr unsafe.Pointer, val int32)
Int64(ptr unsafe.Pointer) int64
SetInt64(ptr unsafe.Pointer, val int64)
Uint(ptr unsafe.Pointer) uint
SetUint(ptr unsafe.Pointer, val uint)
Uint8(ptr unsafe.Pointer) uint8
SetUint8(ptr unsafe.Pointer, val uint8)
Uint16(ptr unsafe.Pointer) uint16
SetUint16(ptr unsafe.Pointer, val uint16)
Uint32(ptr unsafe.Pointer) uint32
SetUint32(ptr unsafe.Pointer, val uint32)
Uint64(ptr unsafe.Pointer) uint64
SetUint64(ptr unsafe.Pointer, val uint64)
Float32(ptr unsafe.Pointer) float32
SetFloat32(ptr unsafe.Pointer, val float32)
Float64(ptr unsafe.Pointer) float64
SetFloat64(ptr unsafe.Pointer, val float64)
}

利用这个 Accessor 可以干很多事情,除了各种函数式编程常用的utility(map/filter/sorted/...)之外。还可以实现一个 plz.Copy 的函数


func Copy(dst, src interface{}) error

Copy 可以用于各种对象绑定的场景



  • Go 不同类型对象之间的值拷贝(struct&map互相转换,兼容指针)

  • JSON 编解码

  • 拷贝 http.Request 到我的 struct 上

  • 拷贝 sql rows 到我的 struct 上

  • Mysql/thrift/redis 等其他协议的编解码


还可以用来实现 plz.Validate 的函数


func Validate(obj interface{}) error

甚至有可能的话,还可以把 .net 的 linq 的概念拿过来


func Query(obj interface{}, query string) (result interface{}, err error)

当然这个工作量非常浩大,比一个JSON解析库繁琐得多。现在只实现了几个概念原型:



用兴趣的朋友可以来发issue:https://github.com/v2pro/wombat/issues

百度AI服务go语言sdk

chenqinghe 发表了文章 • 0 个评论 • 273 次浏览 • 2017-07-07 19:07 • 来自相关话题

利用百度提供的REST API构建的Go语言sdk,目前有语音合成和语音识别功能,更多功能敬请期待。 项目地址:https://github....

Go 語言框架 Gin 終於發佈 v1.2 版本

appleboy 发表了文章 • 7 个评论 • 477 次浏览 • 2017-07-06 16:02 • 来自相关话题

本人轉錄自『Go 語言框架 Gin 終於發佈 v1.2 版本


19807878_1634683919888714_743883353_o


上週跟 Gin 作者 @javierprovecho 討論要發佈新版本,很快地經過一兩天,作者終於整理好 v1.2 版本,除了釋出新版本外,也換了有顏色的 Logo,真心覺得很好看。大家來看看 v1.2 釋出哪些功能,或修正哪些問題。


如何升級


首先來看看如何升級版本,建議還沒有用 vendor 工具的開發者,是時候該導入了。底下可以透過 govender 來升級 Gin 框架。


$ govendor fetch github.com/gin-gonic/gin@v1.2
$ govendor fetch github.com/gin-gonic/gin/render

由於我們新增 Template Func Maps,所以 render 套件也要一併升級喔。


從 godeps 轉換到 govender


Gin 專案本來是用 godeps,但是在套件處理上有些問題,所以我們決定換到穩定些的 govender,看看之後 Go 團隊開發的 dep 可不可以完全取代掉 govendor。


支援 Let's Encrypt


我另外開一個專案 autotls 讓 Gin 也可以支援 Let's Encrypt,這專案可以用在 net/http 套件上,所以基本上支援全部框架,除非搭建的 Http Server 不是用 net/http。使用方式很簡單,如下:


用一行讓 Web 支援 TLS


package main

import (
"log"

"github.com/gin-gonic/autotls"
"github.com/gin-gonic/gin"
)

func main() {
r := gin.Default()

// Ping handler
r.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})

log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
}

自己客製化 Auto TLS Manager


開發者可以將憑證存放在別的目錄,請修改 /var/www/.cache


package main

import (
"log"

"github.com/gin-gonic/autotls"
"github.com/gin-gonic/gin"
"golang.org/x/crypto/acme/autocert"
)

func main() {
r := gin.Default()

// Ping handler
r.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})

m := autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
Cache: autocert.DirCache("/var/www/.cache"),
}

log.Fatal(autotls.RunWithManager(r, &m))
}

支援 Template Func 功能


首先讓開發者可以調整 template 分隔符號,原本是用 {{}},現在可以透過 Gin 來設定客製化符號。


    r := gin.Default()
r.Delims("{[{", "}]}")
r.LoadHTMLGlob("/path/to/templates"))

另外支援 Custom Template Funcs


    ...

func formatAsDate(t time.Time) string {
year, month, day := t.Date()
return fmt.Sprintf("%d/d/d", year, month, day)
}

...

router.SetFuncMap(template.FuncMap{
"formatAsDate": formatAsDate,
})

...

router.GET("/raw", func(c *Context) {
c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
"now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
})
})

...

打開 raw.tmpl 寫入


Date: {[{.now | formatAsDate}]}

執行結果:


Date: 2017/07/01

增加 Context 函式功能


在此版發佈前,最令人煩惱的就是 Bind Request Form 或 JSON 驗證,因為 Gin 會直接幫忙回傳 400 Bad Request,很多開發者希望可以自訂錯誤訊息,所以在 v1.2 我們將 BindWith 丟到 deprecated 檔案,並且打算在下一版正式移除。


// BindWith binds the passed struct pointer using the specified binding engine.
// See the binding package.
func (c *Context) BindWith(obj interface{}, b binding.Binding) error {
log.Println(`BindWith(\"interface{}, binding.Binding\") error is going to
be deprecated, please check issue #662 and either use MustBindWith() if you
want HTTP 400 to be automatically returned if any error occur, of use
ShouldBindWith() if you need to manage the error.`)
return c.MustBindWith(obj, b)
}

如果要自訂訊息,請用 ShouldBindWith


package main

import (
"github.com/gin-gonic/gin"
)

type LoginForm struct {
User string `form:"user" binding:"required"`
Password string `form:"password" binding:"required"`
}

func main() {
router := gin.Default()
router.POST("/login", func(c *gin.Context) {
// you can bind multipart form with explicit binding declaration:
// c.MustBindWith(&form, binding.Form)
// or you can simply use autobinding with Bind method:
var form LoginForm
// in this case proper binding will be automatically selected
if c.ShouldBindWith(&form) == nil {
if form.User == "user" && form.Password == "password" {
c.JSON(200, gin.H{"status": "you are logged in"})
} else {
c.JSON(401, gin.H{"status": "unauthorized"})
}
}
})
router.Run(":8080")
}

大致上是這些大修正,剩下的小功能或修正,請直接參考 v1.2 releases log

Go连接池

chrislee 发表了文章 • 4 个评论 • 344 次浏览 • 2017-07-04 11:21 • 来自相关话题

最近用Go写了两个连接池,goRpcPool查看全部

最近用Go写了两个连接池,goRpcPoolgoRedisPool
作为有几年C++经验的程序员,改用Go后开发效率提高了太多。现在老东家(某Iaas供应商)也开始从C++转向Go了,Go的招聘帖(不管是BAT还是创业公司)也越来越多,希望发展能越来越好。

RobotGo v0.45.0 发布, 增加进程管理和剪贴板

回复

veni 发起了问题 • 1 人关注 • 0 个回复 • 249 次浏览 • 2017-07-02 22:40 • 来自相关话题

Golang 中使用 JSON 的小技巧

taowen 发表了文章 • 3 个评论 • 1173 次浏览 • 2017-06-20 23:32 • 来自相关话题

有的时候上游传过来的字段是string类型的,但是我们却想用变成数字来使用。 本来用一个json:",string" 就可以支持了,如果不知道golang的这些小技巧,就要大费周章了。

参考文章:查看全部

有的时候上游传过来的字段是string类型的,但是我们却想用变成数字来使用。
本来用一个json:",string" 就可以支持了,如果不知道golang的这些小技巧,就要大费周章了。


参考文章:http://attilaolah.eu/2014/09/10/json-and-struct-composition-in-go/


临时忽略struct字段


type User struct {
Email string `json:"email"`
Password string `json:"password"`
// many more fields…
}

临时忽略掉Password字段


json.Marshal(struct {
*User
Password bool `json:"password,omitempty"`
}{
User: user,
})

临时添加额外的字段


type User struct {
Email string `json:"email"`
Password string `json:"password"`
// many more fields…
}

临时忽略掉Password字段,并且添加token字段


json.Marshal(struct {
*User
Token string `json:"token"`
Password bool `json:"password,omitempty"`
}{
User: user,
Token: token,
})

临时粘合两个struct


type BlogPost struct {
URL string `json:"url"`
Title string `json:"title"`
}

type Analytics struct {
Visitors int `json:"visitors"`
PageViews int `json:"page_views"`
}

json.Marshal(struct{
*BlogPost
*Analytics
}{post, analytics})

一个json切分成两个struct


json.Unmarshal([]byte(`{
"url": "attila@attilaolah.eu",
"title": "Attila's Blog",
"visitors": 6,
"page_views": 14
}`), &struct {
*BlogPost
*Analytics
}{&post, &analytics})

临时改名struct的字段


type CacheItem struct {
Key string `json:"key"`
MaxAge int `json:"cacheAge"`
Value Value `json:"cacheValue"`
}

json.Marshal(struct{
*CacheItem

// Omit bad keys
OmitMaxAge omit `json:"cacheAge,omitempty"`
OmitValue omit `json:"cacheValue,omitempty"`

// Add nice keys
MaxAge int `json:"max_age"`
Value *Value `json:"value"`
}{
CacheItem: item,

// Set the int by value:
MaxAge: item.MaxAge,

// Set the nested struct by reference, avoid making a copy:
Value: &item.Value,
})

用字符串传递数字


type TestObject struct {
Field1 int `json:",string"`
}

这个对应的json是 {"Field1": "100"}


如果json是 {"Field1": 100} 则会报错


容忍字符串和数字互转


如果你使用的是jsoniter,可以启动模糊模式来支持 PHP 传递过来的 JSON。


import "github.com/json-iterator/go/extra"

extra.RegisterFuzzyDecoders()

这样就可以处理字符串和数字类型不对的问题了。比如


var val string
jsoniter.UnmarshalFromString(`100`, &val)

又比如


var val float32
jsoniter.UnmarshalFromString(`"1.23"`, &val)

容忍空数组作为对象


PHP另外一个令人崩溃的地方是,如果 PHP array是空的时候,序列化出来是[]。但是不为空的时候,序列化出来的是{"key":"value"}
我们需要把 [] 当成 {} 处理。


如果你使用的是jsoniter,可以启动模糊模式来支持 PHP 传递过来的 JSON。


import "github.com/json-iterator/go/extra"

extra.RegisterFuzzyDecoders()

这样就可以支持了


var val map[string]interface{}
jsoniter.UnmarshalFromString(`[]`, &val)

使用 MarshalJSON支持time.Time


golang 默认会把 time.Time 用字符串方式序列化。如果我们想用其他方式表示 time.Time,需要自定义类型并定义 MarshalJSON。


type timeImplementedMarshaler time.Time

func (obj timeImplementedMarshaler) MarshalJSON() ([]byte, error) {
seconds := time.Time(obj).Unix()
return []byte(strconv.FormatInt(seconds, 10)), nil
}

序列化的时候会调用 MarshalJSON


type TestObject struct {
Field timeImplementedMarshaler
}
should := require.New(t)
val := timeImplementedMarshaler(time.Unix(123, 0))
obj := TestObject{val}
bytes, err := jsoniter.Marshal(obj)
should.Nil(err)
should.Equal(`{"Field":123}`, string(bytes))

使用 RegisterTypeEncoder支持time.Time


jsoniter 能够对不是你定义的type自定义JSON编解码方式。比如对于 time.Time 可以用 epoch int64 来序列化


import "github.com/json-iterator/go/extra"

extra.RegisterTimeAsInt64Codec(time.Microsecond)
output, err := jsoniter.Marshal(time.Unix(1, 1002))
should.Equal("1000001", string(output))

如果要自定义的话,参见 RegisterTimeAsInt64Codec 的实现代码


使用 MarshalText支持非字符串作为key的map


虽然 JSON 标准里只支持 string 作为 key 的 map。但是 golang 通过 MarshalText() 接口,使得其他类型也可以作为 map 的 key。例如


f, _, _ := big.ParseFloat("1", 10, 64, big.ToZero)
val := map[*big.Float]string{f: "2"}
str, err := MarshalToString(val)
should.Equal(`{"1":"2"}`, str)

其中 big.Float 就实现了 MarshalText()


使用 json.RawMessage


如果部分json文档没有标准格式,我们可以把原始的文本信息用string保存下来。


type TestObject struct {
Field1 string
Field2 json.RawMessage
}
var data TestObject
json.Unmarshal([]byte(`{"field1": "hello", "field2": [1,2,3]}`), &data)
should.Equal(` [1,2,3]`, string(data.Field2))

使用 json.Number


默认情况下,如果是 interface{} 对应数字的情况会是 float64 类型的。如果输入的数字比较大,这个表示会有损精度。所以可以 UseNumber() 启用 json.Number 来用字符串表示数字。


decoder1 := json.NewDecoder(bytes.NewBufferString(`123`))
decoder1.UseNumber()
var obj1 interface{}
decoder1.Decode(&obj1)
should.Equal(json.Number("123"), obj1)

jsoniter 支持标准库的这个用法。同时,扩展了行为使得 Unmarshal 也可以支持 UseNumber 了。


json := Config{UseNumber:true}.Froze()
var obj interface{}
json.UnmarshalFromString("123", &obj)
should.Equal(json.Number("123"), obj)

统一更改字段的命名风格


经常 JSON 里的字段名 Go 里的字段名是不一样的。我们可以用 field tag 来修改。


output, err := jsoniter.Marshal(struct {
UserName string `json:"user_name"`
FirstLanguage string `json:"first_language"`
}{
UserName: "taowen",
FirstLanguage: "Chinese",
})
should.Equal(`{"user_name":"taowen","first_language":"Chinese"}`, string(output))

但是一个个字段来设置,太麻烦了。如果使用 jsoniter,我们可以统一设置命名风格。


import "github.com/json-iterator/go/extra"

extra.SetNamingStrategy(LowerCaseWithUnderscores)
output, err := jsoniter.Marshal(struct {
UserName string
FirstLanguage string
}{
UserName: "taowen",
FirstLanguage: "Chinese",
})
should.Nil(err)
should.Equal(`{"user_name":"taowen","first_language":"Chinese"}`, string(output))

使用私有的字段


Go 的标准库只支持 public 的 field。jsoniter 额外支持了 private 的 field。需要使用 SupportPrivateFields() 来开启开关。


import "github.com/json-iterator/go/extra"

extra.SupportPrivateFields()
type TestObject struct {
field1 string
}
obj := TestObject{}
jsoniter.UnmarshalFromString(`{"field1":"Hello"}`, &obj)
should.Equal("Hello", obj.field1)

软文撰写不易,客官点个赞呗:https://github.com/json-iterator/go

wechat_pusher : 基于Golang开发的微信消息定时推送框架

HundredLee 发表了文章 • 2 个评论 • 306 次浏览 • 2017-06-14 12:55 • 来自相关话题

wechat_pusher


Github



  • https://github.com/hundredlee/wechat_pusher

  • 欢迎star && fork && watch

  • 学Golang不久,写一个开源练练手。希望大家提提建议。谢谢

    功能列表


  • 消息推送

    • 模板消息推送

      • model -> message.go

      • task -> template_task.go


    • 图片推送(TODO)

    • 文字推送(TODO)

    • 图文推送(TODO)


  • 日志存储

  • 计划任务


如何开始?


第一步:当然是go get




  • go get github.com/hundredlee/wechat_pusher.git



  • 项目结构如下:


├── README.md
├── config
│   └── config.go
├── config.conf
├── config.conf.example
├── enum
│   └── task_type.go
├── glide.lock
├── glide.yaml
├── hlog
│   ├── filelog.go
│   ├── filelog_test.go
│   └── hlog.go
├── main.go
├── main.go.example
├── models
│   ├── message.go
│   └── token.go
├── redis
│   ├── redis.go
│   └── redis_test.go
├── statics
│   └── global.go
├── task
│   ├── task.go
│   └── template_task.go
├── utils
│   ├── access_token.go
│   ├── crontab.go
│   └── push.go
└── vendor
└── github.com

第二步:创建一个项目


创建配置文件



  • 项目根目录有一个config.conf.example,重命名为config.conf即可

  • 内容如下:


[WeChat]
APPID=
SECRET=
TOKEN=

[Redis]
POOL_SIZE=
TIMEOUT=
HOST=
PASS=
DB=

[Log]
LOG_PATH=


  • WeChat部分

    • APPID && SECRET && TOKEN 这些是微信开发者必须了解的东西。不细讲


  • Redis部分

    • POOL_SIZE 连接池大小 ,整型 int

    • TIMEOUT 连接超时时间 ,整型 int

    • HOST 连接的IP 字符串 string

    • PASS 密码 字符串 string

    • DB 数据库选择 整型 int



  • Log部分



    • LOG_PATH 日志存放文件夹,例如值为wechat_log,那么完整的目录应该是 GOPATH/wechat_log



  • 调用的时候这么写:



conf := config.Instance()
//例如wechat 的 appid
appId := conf.ConMap["WeChat.APPID"]

模板怎么配置



  • 以模板消息作为例子说明:

  • message.go 是模板消息的结构

  • template_task.go 是将一个模板消息封装成任务(template_task.go 是实现了接口task.go的)


mess := models.Message{
ToUser: "openid",
TemplateId: "templateid",
Url: "url",
Data: models.Data{
First: models.Raw{"xxx", "#173177"},
Subject: models.Raw{"xxx", "#173177"},
Sender: models.Raw{"xxx", "#173177"},
Remark: models.Raw{"xxx", "#173177"}}}

//封装成一个任务,TemplateTask表示模板消息任务
task := task.TemplateTask{}
task.SetTask(mess)


  • 以上代码是模板消息的配置,这个微信开发者应该都能看懂。


如何创建一个任务



  • 例如我们要创建一个模板消息定时推送任务

    • 第一步,封装任务

    • 第二步,添加任务,并设置任务类型、并发执行的个数、失败尝试次数等。

    • 第三步,启动任务


  • 我们用示例代码演示整个完整的过程


package main

import (
"github.com/hundredlee/wechat_pusher/enum"
"github.com/hundredlee/wechat_pusher/models"
"github.com/hundredlee/wechat_pusher/task"
"github.com/hundredlee/wechat_pusher/utils"
"runtime"
)

func main() {

runtime.GOMAXPROCS(runtime.NumCPU())
var tasks []task.Task
tasks = make([]task.Task, 100)
mess := models.Message{
ToUser: "oBv9cuLU5zyI27CtzI4VhV6Xabms",
TemplateId: "UXb6s5dahNC5Zt-xQIxbLJG1BdP8mP73LGLhNXl68J8",
Url: "http://baidu.com",
Data: models.Data{
First: models.Raw{"xxx", "#173177"},
Subject: models.Raw{"xxx", "#173177"},
Sender: models.Raw{"xxx", "#173177"},
Remark: models.Raw{"xxx", "#173177"}}}
task := task.TemplateTask{}
task.SetTask(mess)

for i := 0; i < 100; i++ {
tasks[i] = &task
}

utils.NewPush(tasks).SetTaskType(enum.TASK_TYPE_TEMPLATE).SetRetries(4).SetBufferNum(10).Add("45 * * * * *")
utils.StartCron()

}


Run



  • 很简单,当你组装好所有的task以后,直接运行一句话就可以了。


  • utils.NewPush(tasks).SetTaskType(enum.TASK_TYPE_TEMPLATE).SetRetries(4).SetBufferNum(10).Add("45 * * * * *")



  • utils.StartCron()


Contributor


LiteIDE X32 发布,Go 语言开发工具

visualfc 发表了文章 • 2 个评论 • 310 次浏览 • 2017-06-13 11:44 • 来自相关话题

Go 语言开发工具 LiteIDE X32 正式发布。

历经三个月,200 多次源码提交,LiteIDE终于完成了新版本的发布,liteide.org 网站在 查看全部

Go 语言开发工具 LiteIDE X32 正式发布。


历经三个月,200 多次源码提交,LiteIDE终于完成了新版本的发布,liteide.org 网站在 HopeHook 的帮助下也正式推出。


LiteIDE X32 在界面会话、编译系统、源码编辑、代码分析等方面有了很大改进,从去年开始重写的 MulitFolderModel 也终于完成合并到 LiteIDE 的目录窗口中。



  • 提供了更多的界面主题和编辑器配色,感谢 HopeHook

  • 支持外部图标加载功能

  • 支持会话切换功能(会话保持自己的目录和文件)

  • 编译目录支持自定义 GOPATH

  • 编译目录支持更多的设置

  • 调试插件/Go编辑插件支持编译目录的 BUILDFLAGS -tags 设定

  • 完善 Go 代码导航和重构功能

  • 更多的功能更新和 BUG 修复见历史记录




更新记录 2017.6.12 Ver X32



  • LiteIDE

    • support folder build config custom GOPATH

    • support folder build config BUILDFLAGS -tags setup

    • support folder build config TARGETBASENAME setup

    • support session switching for folder/editor

    • support load custom icon library from liteapp/qrc folder (default and folder)

    • reimplemented multifolder model, it took me a long time :)

    • add macOS session menu for native dock menu

    • recent menu sync for multi windows

    • gotools support +build source navigate (single file or -tags setup)


  • LiteApp

    • add the session switching function

    • add autosavedocument emit message option

    • add max editor tab count option

    • add option action to standard toolbar

    • add tool window use shortcuts option for unstandard keyboard option

    • add exit liteide ctrl+q on windows

    • add themes (carbon.qss gray.qss sublime.qss) for liteide & beautify old themes, thanks for hope hook

    • editor tab context add open terminal here action

    • folders context menu add open in new windows action (new folder session)

    • folder view add show showdetails action

    • fix folder sync editor incorrect on macOS

    • fix webview and debug console qss

    • fix folders tool window enter key to jump

    • fix exit error save session by ctrl+q on macos

    • fix newfile dialog space name

    • update folder tool window showInExporer showInShell action text


  • LiteFind

    • find files add auto swith current folder checkbox

    • find in editor add show replace mode checkbox

    • filesearch enable replace whitespace or empty

    • editor replace all in one edit block for ctrl+z once undo


  • LiteBuild

    • add custom GOPATH in build config for build/debug/GolangEdit

    • add custom share-value BUILDFLAGS in build config for build/debug/GolangEdit

    • add custom TARGETBASENAME in build config for build/debug

    • support BUILDFLAGS -tags for build/debug/GolangEdit

    • update gosrc.xml to export custom value and share-value

    • folders tool window context menu add Go build configuration action

    • folders tool window context go tool use Go build configuration setup

    • fix stop action for kill process


  • LiteDebug

    • console use editor color scheme

    • support LiteBuild folder build config BUILDFLAGS/BUILDARGS -tags flag setup


  • DlvDebugger

    • fix process identify for auto exit


  • LiteEnv

    • default env /usr/local/go on macosx

    • update macosx cross env GOROOT for system


  • LiteEditor

    • context menu add convert case menu

    • go.snippet add iferr

    • update sublime.xml / sublime-bold.xml, thanks for hopehook hopehook@qq.com">hopehook@qq.com

    • alt+backspace delete serial whitespaces

    • option font QComboBox to QFontComboBox, add restore DefaultFont action

    • option add show monospace font check

    • option file types sort mimetype, show custom extsition first


  • GolangPackage

    • gopath setup add use sysgopath/litegopath check


  • GolangPlay

    • fix goplay use goenvironment


  • GolangDoc

    • change golang api index search for go/api folder


  • GolangEdit

    • add go root source readonly setup option

    • support folder go build config BUILDFLAGS/BUILDARGS -tags flag setup

    • fix interface type by gotools

    • fix find process stop and run

    • fix lookup guru for source query


  • GolangAst

    • fix astview enter key to jump


  • FileBorwser

    • fix file system enter key to jump


  • gotools

    • fix types interface method

    • types support +build for single source

    • types support -tags flag


  • tools

    • add new exportqrc tool for export liteide all build-in images


GO解析PHP通过PHPCGI进行渲染

alalmn 发表了文章 • 0 个评论 • 242 次浏览 • 2017-06-10 15:06 • 来自相关话题

GO解析PHP通过PHPCGI 因为手上有别的事情这个项目就放这了 有兴趣的小伙伴大家子看吧 我QQ:29295842 GIT地址:查看全部

GO解析PHP通过PHPCGI
因为手上有别的事情这个项目就放这了
有兴趣的小伙伴大家子看吧
我QQ:29295842
GIT地址:https://github.com/webxscan/gophp/tree/master/gophp
GIT地址:https://github.com/webxscan/gophp/tree/master/gophp
GIT地址:https://github.com/webxscan/gophp/tree/master/gophp


golangPHPcgi GOphp--GO解析PHP源码并实现一个miniPHP服务起器


by


golang php cgi github:https://github.com/webxscan/gophp
BLOG: http://blog.csdn.net/webxscan/
BY:斗转星移 QQ:29295842


软件目的


实现一个本地PHP解析器,不用使用阿帕奇或者IIS。
这样就可以实现很多自定义扩展。
软件目前写了4天,还有很多不完美的地方还希望大家予以纠正。

go 的 json 标准库有接班人了

taowen 发表了文章 • 13 个评论 • 886 次浏览 • 2017-06-02 10:57 • 来自相关话题

json.Unmarshal 替换成 jsoniter.Unmarshal

json.Marshal 替换成 jsoniter.Marshal查看全部

json.Unmarshal 替换成 jsoniter.Unmarshal


json.Marshal 替换成 jsoniter.Marshal


所有的行为和标准库都一模一样



  • 无需代码生成,基于高速的反射实现。因为缓存了类型信息,比标准库的反射要快很多。

  • 支持所有的 json:"field" tag 标记

  • 支持 json.Marshaler 和 json.Unmarshaler 自定义扩展

  • 支持 json.Number

  • 支持 json.RawMessage

  • 修正了所有之前和标准库不兼容的地方(比如字段名,是否默认支持private成员等)


除了把 json 换成 jsoniter,什么都不需要改。再也不用 easyjson 这样的代码生成的库来加速json的编解码了。


github地址:https://github.com/json-iterator

gRPC负载均衡的正确姿势

stirlingx 发表了文章 • 6 个评论 • 542 次浏览 • 2017-06-01 19:39 • 来自相关话题

因为官方的grpc-go客户端只实现了一个RoundRobin load balancer,所以写了一个库,增加了Random、ketama策略,并可以很方便的增... 查看全部

因为官方的grpc-go客户端只实现了一个RoundRobin load balancer,所以写了一个库,增加了Random、ketama策略,并可以很方便的增加新的策略。


项目地址: https://github.com/liyue201/grpc-lb