stevewang

第 1556 号会员 /

回复了 shenjiayu 创建的主题: 有关HTTPS的问题

@#11

还有端口权限(https是系统端口443)防火墙权限等等系统设置可以检查一下。

回复了 chenhao 创建的主题: 指针区别求教

我的理解:

uintptr是runtime层面看到的指针,p是语言层面看到的指针,unsafe.Pointer介于两者之间并做为转换器,即必须通过unsafe.Pointer才能把p转换成uintptr。

package main

import(
    "fmt"
    "unsafe"
)

func main() {
    p := new(int)
    // fmt.Println(uintptr(p)) <== 编译错误
    fmt.Println(uintptr(unsafe.Pointer(p)))
}

回复了 dxhdxh2k 创建的主题: append的两种实现都可以,不知区别在何处?

第一种用法没有必要,因为你打包成[]string,又用...解包,然后编译器把参数传给append时又要打包。。。 所以你的打包和解包是冗余的步骤。 没注释掉的代码不能编译通过,是因为这里append接受的不定参数类型必须是string,所以[]string类型不符。

回复了 looo3ooo 创建的主题: 关于空接口的疑惑

可以考虑用reflect

package main

import (
    "errors"
    "fmt"
    "reflect"
)

type Log struct{}

func AllPage(s interface{}, offset, limit int) (interface{}, error) {
    value := reflect.ValueOf(s)
    if value.Type().Kind() != reflect.Slice {
        return nil, errors.New("wrong type")
    }
    size := value.Len()
    if size == 0 {
        return nil, errors.New("no data")
    }
    if size > limit {
        end := offset + limit
        if end > size {
            end = size
        }
        s = value.Slice(offset, end).Interface()
    }
    return s, nil
}

func main() {
    var logs [10]*Log
    sub, err := AllPage(logs[:], 7, 5)
    fmt.Println(sub.([]*Log), err)
}

回复了 kjfcpua 创建的主题: ,java类有implements可以知道类实现了哪个接口,go里面当我查看第三方源码的时候,如何能知道某个struct实现了那个接口呢。难道必须去源码里面看有没有这个接口的实现方法,不能像java那样直接的看到implements就知道实现那个接口吗。。。

当然,一个type实现的接口是有上限的。比如一个type有一个方法,它就只能实现两个接口;有两个方法,就实现4个接口;三个方法,就实现7个接口。

回复了 kjfcpua 创建的主题: ,java类有implements可以知道类实现了哪个接口,go里面当我查看第三方源码的时候,如何能知道某个struct实现了那个接口呢。难道必须去源码里面看有没有这个接口的实现方法,不能像java那样直接的看到implements就知道实现那个接口吗。。。

在go里,一个type只提供功能,它不知道自己实现了那些接口,实现的接口是由功能使用者决定的。一个*os.File,我可以认为它实现了Reader接口,也可以认为它实现了Writer接口,或者认为它实现了ReadWriter接口,这都取决于使用*os.File的代码需要它的什么功能和做什么程度的抽象。

回复了 xiaolongren25 创建的主题: 如何安全关闭channel

用一个channel做控制就可以,写的goroutine在这个channel上收到信号就退出。

package main
import (
    "fmt"
    "sync"
    "time"
)
func main() {
    var wg sync.WaitGroup
    exit := make(chan struct{})
    ch := make(chan int, 1)
    send := func(n int) {
        defer wg.Done()
        for {
            select {
            case ch <- n:
                time.Sleep(time.Second)
            case <-exit:
                return
            }
        }
    }
    wg.Add(10)
    // 10个goroutine写
    for i := 0; i < 10; i++ {
        go send(i)      
    }
    // 一个goroutine读
    go func() {
        for {
            n, ok := <-ch
            if !ok {
                return
            }
            fmt.Println(n)
        }
    }()
    time.Sleep(time.Second*10)
    close(exit)
    wg.Wait()
    close(ch)
}

回复了 _____k0_____ 创建的主题: Golang是否真不需要epoll/select/poll的支持了?

其实我觉得目前还是需要的,如果能在一个goroutine里处理多个tcp连接,在一些特定场景下会对性能提升有很大帮助。 但是随着channel通信效率的不断改进,这个需求就会变得越来越没有必要。

回复了 zbzpo2002 创建的主题: GDB debug Golang 1.3

go现在对gdb支持不好,go1.3的支持度更差。go team的人在考虑开发一个go自身的debugger,但是似乎还没有开发计划。 先放弃用gdb把,用打印信息调试没有想象中的那么困难。

回复了 chenhao 创建的主题: golang如何获取到err(调用Windows 控制台程序和dll时)

最好把简化的可重现问题的代码贴出来看看。 我试了没有问题,代码如下:

C++代码:

// hello.cpp
#include <stdio.h>

int main() {
    fprintf(stderr, "Hello, world!");
    return 0;
}

go代码:

package main

import (
    "bytes"
    "fmt"
    "os/exec"
)

func main() {
    cmd := exec.Command(`hello.exe`)
    w := bytes.NewBuffer(nil)
    cmd.Stderr = w
    if err := cmd.Run(); err != nil {
        fmt.Printf("err: %s\n", err)
        return
    }
    fmt.Printf("output: %s\n", w.Bytes())
}

在windows7 32bit下调试通过,输出:

output: Hello, world!

回复了 xiaolongren25 创建的主题: 如何安全关闭channel

先把写的goroutine停下来就可以安全关闭channel了。 例如:

package main
import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    ch := make(chan int, 1)
    send := func(m, n int) {
        for i := m; i <= n; i++ {
            ch <- i
        }
        wg.Done()
    }
    wg.Add(3)
    go send(1, 10)
    go send(11, 20)
    go send(21, 30)
    go func() {
        for {
            n, ok := <-ch
            if !ok {
                return
            }
            fmt.Println(n)
        }
    }()
    wg.Wait()
    close(ch)
}