我有一个棘手的问题,我不确定Go是否可行,基本上我正在编写一个实现简单二进制搜索的包,我想返回一个由用户定义的struct的值,即不在包装中。
因此我想要一个包中的函数,该函数可以分配给本地定义的结构,也就是说package main
。
所以在包中是二进制搜索的功能:
package binsearch
func (f *SomeStruct) Get(lookup uint) (int, uint, bool) {
min := 0
max := len(f.Key)-1
at := max/2
for {
current := f.Key[at]
if lookup<current {
max = at-1
} else {
if lookup>current {
min = at+1
} else {
return at, f.Value[at], true // found
}
}
if min>max {
return 0, 0, false // doesn't exist
}
at = (max+min)/2
}
}
然后主要是:
package main
type mystruct struct {
Key []uint
Value []uint
}
func main() {
test := new(mystruct)
// Then add some data here
i, value, ok := test.Get(12345)
}
不知何故,我需要在package main
中定义binsearch.Get
函数应该应用于mystruct
。这可能吗?
答案 0 :(得分:3)
以下是使用接口的样子:
package binsearch
type Searchable interface {
Key(pos int) uint
Value(pos int) uint
Len() int
}
func Get(s Searchable, lookup uint) (int, uint, bool) {
min := 0
max := s.Len()-1
at := max/2
for {
current := s.Key(at)
if lookup<current {
max = at-1
} else {
if lookup>current {
min = at+1
} else {
return at, f.Value(at), true // found
}
}
if min>max {
return 0, 0, false // doesn't exist
}
at = (max+min)/2
}
}
和主要
package main
import (
"path/to/binsearch"
)
type mystruct struct {
key []uint
value []uint
}
func (m *mystruct) Key(pos int) uint {
return m.key[pos]
}
func (m *mystruct) Value(pos int) uint {
return m.value[pos]
}
func (m *mystruct) Len() int {
return len(m.key)
}
func main() {
test := new(mystruct)
// Then add some data here
i, value, ok := binsearch.Get(test, 12345)
}
答案 1 :(得分:1)
不,您必须使用界面并在mystruct
上定义。
type BinarySearchable interface {
Keys() []uint
Values() []uint
}
func Get(bs BinarySearchable, lookup uint) (int, uint, bool) {
keys := bs.Keys()
vals := bs.Values()
min := 0
max := len(keys) - 1
at := max / 2
for {
current := keys[at]
if lookup < current {
max = at - 1
} else {
if lookup > current {
min = at + 1
} else {
return at, vals[at], true // found
}
}
if min > max {
return 0, 0, false // doesn't exist
}
at = (max + min) / 2
}
}
type mystruct struct {
keys []uint
values []uint
}
func (ms *mystruct) Keys() []uint {
return ms.keys
}
func (ms *mystruct) Values() []uint {
return ms.values
}
func main() {
test := &mystruct{[]uint{12, 123456, 13}, []uint{1,2,3}}
fmt.Println(Get(test, 123456))
}
答案 2 :(得分:1)
您可以在没有接口的情况下执行此操作,但必须将mystruct类型转换为binsearch.SomeStruct类型。这是因为binsearch.Get函数被定义为将指向binsearch.SomeStruct的指针作为接收器,并且在这种情况下Go不会为您自动转换类型。
没有通用的方法可以执行此操作,但特定于您的应用程序的方法可能如下所示:
s := &SomeStruct{}
copy(test.Key, s.Key)
copy(test.Value, s.Value)
i, value, ok := s.Get(12345)
答案 3 :(得分:0)
你所描述的方式是不可能的。 Golang使用的是接口的概念:您定义一组给定结构必须实现的方法。
type Fooer interface {
Bar(i int)
}
然后,您可以定义一个函数或方法,将此类型的变量作为参数,并使用已定义的方法集来完成其工作。
func Foo(a Fooer) {
// Do you stuff here using the Bar() method
}
约定是为接口命名,以-er
结尾。您可以在包含fmt
和Stringer
的{{1}}包中查看接口示例,或者更接近于您的示例,在Scanner
包中定义名为{{1}的接口}(全名是sort
,这是约定的一个中断,但实际上比所述约定更干净,因为包中只有一个接口,并且包是为了使用这个接口而构建的。)