Golang有一个问题困扰我.说我有两个结构:
type Dog struct {
Name string
Breed string
Age int
}
type Cat struct {
Name string
FavoriteFood string
Age int
}
Run Code Online (Sandbox Code Playgroud)
当我尝试进行排序[]*Dog和[]*Cat通过Age,我必须定义2个不同类型的结构,如:
type SortCat []*Cat
func (c SortCat) Len() int {//..}
func (c SortCat) Swap(i, j int) {//..}
func (c SortCat) Less(i, j int) bool {//..}
type SortDog []*Dog
func (c SortDog) Len() int {//..}
func (c SortDog) Swap(i, j int) {//..}
func (c SortDog) Less(i, j int) bool {//..}
Run Code Online (Sandbox Code Playgroud)
一个自然的想法是使用接口函数实现一些SortableByAge …
我试图解决可以在这里找到的SPOJ问题
以下是我的解决方案:
package main
import "fmt"
import "bufio"
import "os"
func main() {
var n, k int
var num int
var divisible int
in := bufio.NewReader(os.Stdin)
fmt.Fscan(in, &n)
fmt.Fscan(in, &k)
for n > 0 {
fmt.Fscan(in, &num)
if num%k == 0 {
divisible++
}
n--
}
fmt.Println(divisible)
}
Run Code Online (Sandbox Code Playgroud)
代码工作正常.这里的问题是我在SPOJ中执行它时会出现超时.
我是第一次使用,fmt.Scan但后来我遇到了这个线程,建议我使用bufio更快的输入扫描.
但我仍然遇到超时问题.我只是循环以获取所有输入,并且在此循环内我确定输入是否可被整除.所以,我认为它不是循环,而是输入扫描需要时间.如何改进这一点以更快地读取输入?或者是其他地方的问题?
是否有内置方式,或合理的标准包,允许您将标准UUID转换为短链接,以实现更短的URL?
即利用更大范围的字符,例如[A-Za-z0-9]输出更短的字符串.
我知道我们可以使用base64对字节进行编码,如下所示,但是我正在创建一个看起来像"单词"的字符串,即no +和/:
id = base64.StdEncoding.EncodeToString(myUuid.Bytes())
Run Code Online (Sandbox Code Playgroud) 我需要检查接口值是否为"nil".
但通过使用反射,它给了我一个错误:
反映:在struct Value上调用reflect.Value.Bool.
通过nil它没有给人一种错误的nil价值.
我正在尝试使用反射来构建一个例程,该例程将列出传入的任意结构中的所有字段的名称,种类和类型.这是我到目前为止所得到的:
type StatusVal int
type Foo struct {
Name string
Age int
}
type Bar struct {
Status StatusVal
FSlice []Foo
}
func ListFields(a interface{}) {
v := reflect.ValueOf(a).Elem()
for j := 0; j < v.NumField(); j++ {
f := v.Field(j)
n := v.Type().Field(j).Name
t := f.Type().Name()
fmt.Printf("Name: %s Kind: %s Type: %s\n", n, f.Kind(), t)
}
}
func main() {
var x Bar
ListFields(&x)
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
Name: Status Kind: int Type: StatusVal
Name: FSlice Kind: slice Type:
Run Code Online (Sandbox Code Playgroud)
当字段是切片时,类型为空.我尝试了几种方法来获取切片的数据类型,但所有尝试都导致了恐慌......通常是这样的:
reflect: …Run Code Online (Sandbox Code Playgroud) 我希望在Go中编写的webapp中使用MongoDB.
我可以拥有一个mgo.Session并在Web应用程序中同时使用它.例如inhttp.Handler
或者我应该打电话Session.Copy和Session.Close- >制作会话池.
这听起来很矛盾,我读到池已经在里面实现了mgo.Session,我可以同时使用会话,在其他地方,我读到我需要Copy和Close.
使用该log.Lshortfile标志时,记录器会在所有日志行前加上记录器函数调用的文件名和行号,例如:
myfile.go:14: Hello, world!
如果我像这样包装日志函数,例如:
func info(pattern string, args ...interface{}) {
myLogger.Printf(pattern + "\n", args...)
}
Run Code Online (Sandbox Code Playgroud)
此函数发出的每一行都将以Printf调用的行号为前缀.这是预期的,但是期望的行为是每行都以要info调用的行的行号为前缀.
它有什么办法吗?
我正在使用github.com/fatih/structs包将结构的所有字段的值转换[]interface{}为toValues()函数.看到这里.这很好,但最终我想通过使用csv包将值写入csv文件.该csv.Write()功能需要[]string输入.
简而言之:如何轻松地将输出转换toValues()为字符串数组?
我遇到了将星期几字符串转换为time.Weekday值的问题。我找不到time包中内置的任何东西。
然后我编写了这个简单的函数(满足了我的需求):
var daysOfWeek = [...]string{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
}
func parseWeekday(v string) (time.Weekday, error) {
for i := range daysOfWeek {
if daysOfWeek[i] == v {
return time.Weekday(i), nil
}
}
return time.Sunday, fmt.Errorf("invalid weekday '%s'", v)
}
Run Code Online (Sandbox Code Playgroud)
在 Golang 中是否有其他推荐或更惯用的方法来执行此转换?
谢谢!
在Go的中runtime/proc.go,下面显示了一段代码:
// funcPC返回函数f的入口PC。
//假定f是一个func值。否则,行为是不确定的。
// CAREFUL:在具有插件的程序中,funcPC可以
为同一函数返回不同的值(//因为
地址空间中实际上存在同一函数的多个副本)。为了安全起见,请勿
在任何==表达式中使用//函数的结果。
// 仅将结果用作开始执行代码的地址是安全的。
//go:nosplit
func funcPC(f interface{}) uintptr {
return **(**uintptr)(add(unsafe.Pointer(&f), sys.PtrSize))
}
Run Code Online (Sandbox Code Playgroud)
我不明白的是为什么不使用*(* uintptr)而不是**(** uintptr)?
因此,我在下面编写了一个测试程序来弄清楚。
package main
import (
"fmt"
"unsafe"
)
func main(){
fmt.Println()
p := funcPC(test)
fmt.Println(p)
p1 := funcPC1(test)
fmt.Println(p1)
p2 := funcPC(test)
fmt.Println(p2)
}
func test(){
fmt.Println("hello")
}
func funcPC(f func()) uintptr {
return **(**uintptr)(unsafe.Pointer(&f))
}
func funcPC1(f func()) uintptr {
return *(*uintptr)(unsafe.Pointer(&f))
}
Run Code Online (Sandbox Code Playgroud)
p不等于p1的结果使我感到困惑。当类型相同时,为什么p的值不等于p1的值?