Go:Local Struct的包函数接口

时间:2014-08-05 13:40:03

标签: go

我有一个棘手的问题,我不确定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。这可能吗?

4 个答案:

答案 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))
}

playground

答案 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结尾。您可以在包含fmtStringer的{​​{1}}包中查看接口示例,或者更接近于您的示例,在Scanner包中定义名为{{1}的接口}(全名是sort,这是约定的一个中断,但实际上比所述约定更干净,因为包中只有一个接口,并且包是为了使用这个接口而构建的。)