首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
beego
V2EX  ›  Go

Go 的几大坑

  •  1
     
  •   hijoker · 354 天前 · 3984 次点击
    这是一个创建于 354 天前的主题,其中的信息可能已经有所发展或是发生改变。
    可能有些不准确,别跟我说用了 N 多的 trick 怎么实现了,我说的是开箱即用
    1. 接口没有默认实现, 几个数据结构实现了某个接口需要有统一的行为,每个都得写一个几乎同样的方法,太蛋疼了
    2. panic 的堆栈信息,捕获是捕获了,我要把他打到日志里去??
    3. 日志框架,默认能做到打印行号,打印时间,打印级别,控制按日志级别输出,对日志自动分片压缩的几乎没有
    4. 蛋疼的类型信息
    48 回复  |  直到 2018-10-01 18:30:21 +08:00
        1
    hijoker   354 天前
    panic 的堆栈信息可以如下做
    defer func() {
    if r := recover(); r != nil {
    logUtil.Error.Printf("panic, %s, collecing ends", fmt.Sprintf("%v",r))
    return
    }
    }()
        2
    Mohanson   354 天前
    现在日志很少会靠程序自动写了, 都是程序打印到标准输出, 然后 supervisor 或 heka 等服务捕获, 并做日志分割, 存储等功能.
        3
    heimeil   354 天前
    1. 你可以考虑一下把接口拆分得颗粒度小一点,再组合合适的功能到一起
    2. 最好做到 no panic,做好错误检查比 defer recover 好得多
        4
    hijoker   354 天前
    @Mohanson 并不是每个都搞这些高大上的
        5
    Immortal   354 天前
    对日志自动分片压缩的几乎没有
    这个倒是真的 得自己实现了
        6
    xkeyideal   354 天前   ♥ 12
    1 -> 对语言了解不深,既然是 interface,自己不实现,难道用意念编程?
    2 -> panic 对应的还有个叫 recover, 参考一楼的答案,学艺不精
    3 -> 日志框架,你别告诉大家说你用标准库的,现在都用第三方或自己写,有个叫 logrus 的据说挺好用
    4 -> 类型信息缺失挺蛋疼,还不支持 int,int32 这些类型的自动转义,这个算个槽点

    楼主应该是刚入门的级别,建议多修炼修炼,吐槽的都没到点上

    你应该吐槽:
    1. 为毛没有泛型?
    2. 从来没见过这么垃圾的包管理?
    3. 什么玩意,写个项目还要定义 gopath 这个环境变量?
    4. error 处理这他妈垃圾!!!
    5. 为毛编译这么快,老子都没反应过来,c++不是 make 一下可以玩一把手游的么
        7
    bonfy   354 天前
    包管理是可以吐槽

    error 处理写多了,倒是没有感觉了,至少好处是每个 error 都处理,问题比以前写 Python 少多了
        8
    tourist2018   354 天前
    日志框架,默认能做到打印行号,打印时间,打印级别,控制按日志级别输出,对日志自动分片压缩的几乎没有

    这个一般是第三方实现的吧 而且 go 的 log 能提供的东西已经很多了
        9
    zwpaper   354 天前
    @xkeyideal #6 日志框架也真的是 槽点,logrus 的 issue 好几年了,行号的功能楞是没加上
        10
    feiyuanqiu   354 天前
    感觉最近 go 代替了 php,成为了最引战语言...是不是说明 go 最近发展势头还不错?
        11
    hcymk2   354 天前
    golang 中根据首字母的大小写来确定可以访问的权限
    当初没看文档,被这个坑的不要不要的。
        12
    xkeyideal   354 天前
    @zwpaper 打印行号,打印时间,打印级别,控制按日志级别输出,对日志自动分片压缩,打印调用的堆栈信息,按照执行完整流程作用域输出等等,这些功能好像并不难实现,所以自己写个就好啦,想要啥功能自己加,还能为项目需要个性化定制
        13
    lideshun123   354 天前
    学艺不精也来喷,你看 V2 多友善
        14
    zarte   354 天前
    map slice 默认传引用这个比较坑。
        15
    janxin   354 天前
    1 无解,换个语言可破;
    2 是用法你没了解;
    3 这个库有的,你再找找?不过这样程序会慢,个人建议性能敏感程序不要打印文件行号信息;
    4. 换个 Rust 试试?
        16
    Aruforce   354 天前   ♥ 1
    我想吐槽的是 p1 *P =&P{}和 p2 *P=P{}。。居然都尼玛可以。。。还有接受指针压栈的函数。。在写代码的时候 p3 P =P{}。。p3 也能直接调用。。。
    综上 。。所写非所得。。。 每次写代码前都要先想下 p 到底是不是指针。。。也许是我写的太少的原因。。。
    其他的泛型。。。error 处理方式。。包管理。。。还没有 ThreadLocalStorage。。其他什么的就不 BB 了。。。
        17
    jitongxi   354 天前
    楼主玩 go 一两天的经验。。。
        18
    janxin   354 天前
    @Aruforce 我想要 ThreadContext 啊,一个 ctx 显示传来传去非常蛋疼。

    没 get 到第一个问题是什么问题,编译不过的吧?能否给个代码看看?另外那个真的不是传统意义上的“指针”...
        19
    darrh00   354 天前
    打印行号: 默认有

    打印时间 : 默认有

    打印级别,控制按日志级别输出: 关于这个非常同意 Dave cheney 的观点,完全没必要分很细的日志界别 [链接]!( https://dave.cheney.net/2015/11/05/lets-talk-about-logging)

    日志自动分片压缩: logrotate 写个几行配置,然后程序里响应一下 SIGHUP 信号,重新开一下日志文件,搞定。
        20
    zwpaper   354 天前 via iPhone
    @xkeyideal 自己写一个是一方面,我现在确实是改的 logrus,但是有一个好的库,还是会更好
        21
    hijoker   354 天前
    @darrh00 我觉得根据日志级别控制输出是很常用的功能。。。。
    还有 logrotate 这个,真心在 windows 上就不好搞了
        22
    aliipay   354 天前
    @Aruforce 我都是跟这感觉写的,都不管指针不指针的
        23
    hijoker   354 天前
    @xkeyideal 你看懂了么,interface 的默认实现??
    就是说几个
    type struct1 struct{...}
    type struct2 struct{...}
    都实现了某个接口,这个接口其实对于大家都是一样的,如果有个默认实现就好了,不用每个 struct 都去写同样的方法,除了 receiver 不一样之外
        24
    hijoker   354 天前
    @lideshun123 请指教
        25
    hijoker   354 天前
    @jitongxi 我玩了几天也这就遇到了这些问题,实在惭愧
        26
    silov   354 天前
    Golang 新手签到,刚刚遇到一个小坑。。。时间格式化的 Fomat、Parse 方法的格式参数。。。。竟然是那种写死的字符串。。。真是写的时候就透露着一股尴尬。。。

    ```golang
    datetime := time.Now().Format("2006-01-02 15:04:05") //后面的参数是固定的 否则将无法正常输出
    ```
        27
    hijoker   354 天前
    @zwpaper 我也是这样想的,感觉 Go 社区走的路子怪怪的
        28
    janxin   354 天前
    @hijoker 如果是这样你试试 embed struct ?
        29
    xkeyideal   354 天前
    @Aruforce 你这个完全是 go 好心办坏事,go 怕一些不懂或者不完全懂指针的用户指针的用法不对,造成一些他们意向不到的问题,所以将你说的这些情况都给兼容了。如果是玩过 C/C++的,根本不会有这种疑问,指针和形参还是很好区分的,另建议使用指针操作。
    go 里面玩指针就按照 C/C++那套整就完全没问题,注意一下 map, slice 默认是引用传递( go 官方不承认用“引用传递”这个说法)
        30
    xkeyideal   354 天前   ♥ 1
    @silov 对于操作时间,给你个建议,任何时候都带上时区去计算,否则对时间强依赖的项目,死都不知道怎么死的,运维给你服务器整个 UTC 时区,你按照北京时间算
        31
    lwldcr   354 天前
    log 确实没有像 java log4j 那种功能齐备的库
    不过我自己用的时候标准库的 log 上自定义部分功能+logrotate 基本满足需求了
        32
    hijoker   354 天前
    @janxin 是个办法,谢谢,
        33
    xkeyideal   354 天前
    @hijoker 所以说你是第一天玩呢!!
    你在 struct1 和 struct2 上都”继承“一个基类 struct3,然后让 struct3 去实现你想要的同一样且不需要写两次的接口不就行了么?

    想玩面向对象编程那套,go 并不是不是可以,只不过现有的基础设施比较简陋,实现的面向对象不能像 C++和 Java 那么简便和高大上罢了

    多看看一些开源项目对深入提升比较有好处
        34
    silov   354 天前
    @xkeyideal 感谢提醒,我看下
        35
    darrh00   354 天前
    @hijoker

    光要控制日志输出,很容易, 错误信息 info 输出,调试信息 debug 输出,加一个控制开关关闭 debug 输出
    分那么多 info,warn,error,fatal 就是脱裤子放*, 你真的会用那么多级别来控制程序的日志输出?
    交给运维人员,运维人员会用你那么多的参数设置?

    windows 这个真不懂了,没有在 windows 上跑服务程序的经验。
        36
    whoami9894   354 天前 via Android   ♥ 1
    哈哈我也来说一个坑:
    结构体是值类型,切片是引用类型
    我把一个结构体传入函数(不传指针),函数里修改结构体内容(比如 append 结构体替换原有结构体只全局可见)。如果直接修改结构体里的切片则是全局可见
        37
    RaynorGu   354 天前
    @darrh00 debug, info, warning, error 这四个级别还是要的,debug 是调试的时候打印信息,info 是线上一些做事情的日志,比如定时器啊之类的,这样查问题可以看到有没有做,warning 就是一些不是很重要的错误,error 就是重要的错误
        38
    whoami9894   354 天前 via Android
    @whoami9894
    append 结构体替换原有结构体只局部可见
        39
    jinzhe   354 天前
    @silov 自己写个辅助函数转一下即可
    ```go

    // Format time.Time struct to string
    // MM - month - 01
    // M - month - 1, single bit
    // DD - day - 02
    // D - day 2
    // YYYY - year - 2006
    // YY - year - 06
    // HH - 24 hours - 03
    // H - 24 hours - 3
    // hh - 12 hours - 03
    // h - 12 hours - 3
    // mm - minute - 04
    // m - minute - 4
    // ss - second - 05
    // s - second = 5
    func FormatDate(format string, t ...time.Time) string {
    var datetime time.Time
    if len(t) == 0 {
    datetime = time.Now()
    } else {
    datetime = t[0]
    }

    res := strings.Replace(format, "MM", datetime.Format("01"), -1)
    res = strings.Replace(res, "M", datetime.Format("1"), -1)
    res = strings.Replace(res, "DD", datetime.Format("02"), -1)
    res = strings.Replace(res, "D", datetime.Format("2"), -1)
    res = strings.Replace(res, "YYYY", datetime.Format("2006"), -1)
    res = strings.Replace(res, "YY", datetime.Format("06"), -1)
    res = strings.Replace(res, "HH", fmt.Sprintf("%02d", datetime.Hour()), -1)
    res = strings.Replace(res, "H", fmt.Sprintf("%d", datetime.Hour()), -1)
    res = strings.Replace(res, "hh", datetime.Format("03"), -1)
    res = strings.Replace(res, "h", datetime.Format("3"), -1)
    res = strings.Replace(res, "mm", datetime.Format("04"), -1)
    res = strings.Replace(res, "m", datetime.Format("4"), -1)
    res = strings.Replace(res, "ss", datetime.Format("05"), -1)
    res = strings.Replace(res, "s", datetime.Format("5"), -1)
    return res
    }```
        40
    bobuick   354 天前
    日志是你没用对库吧。std 里日志没有那么完整的支持,这种一般都不会在 std 里,c++, java 也是这样。
        41
    Leigg   354 天前 via iPhone
    为什么要把 panic 错误打印到日志?这说明程序写的并不够健壮,panic 错误是要爆出来给人看的,不然程序多少暗坑都不知道
        42
    reus   354 天前   ♥ 1
    1, embedded field
    2, runtime.Callers
    3, 自己写
    4, 蛋疼可能是肾亏
        43
    icris   354 天前
    @xkeyideal #6
    是 interface 就得自己实现没有什么理论依据啊,连 Java 的 interface 都能放 default 了,Go 以后也不一定不加
        44
    xeaglex   353 天前
    @xkeyideal 并非引用传递,看源码就知道了,是值传递了指针成员变量。
        45
    blless   353 天前 via Android
    我也说一个…遍历一个结构体 slice 然后在循环内部取遍历出来的结构体地址…发现都是同一个地址
        46
    sxw11   353 天前 via Android
    包管理,泛型,gopath 三大坑!谁用税知道!
        47
    mosliu   353 天前
    感觉最大的坑就是包管理
    现在 go mod 稍有改善的迹象
        48
    wenzhoou   353 天前 via Android
    @silov 这个真的是很尴尬啊。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1741 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 34ms · UTC 16:43 · PVG 00:43 · LAX 09:43 · JFK 12:43
    ♥ Do have faith in what you're doing.