I am following instructions in https://golang.org/doc/code.html#Workspaces link and I build my first Go program.
So, I tried to make library with this instruction = https://golang.org/doc/code.html#Library
and everything is perfect until building hello.go, its gives me this error.
/hello.go:10:13: undefined: stringutil.Reverse
I've already rebuild my reverse.go.
Thats my code:
package main
import (
"fmt"
"github.com/d35k/stringutil"
)
func main() {
fmt.Printf(stringutil.Reverse("!oG ,olleH"))
}
that's my reverse.go (same as docs)
package stringutil
func reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
and my gopath variable
export GOPATH=$HOME/GoLang
and my files ar in
GoLang/src/github.com/mygithubusername/
Golang Tour specify exported name as
A name is exported if it begins with a capital letter. And When
importing a package, you can refer only to its exported names. Any
"unexported" names are not accessible from outside the package.
Change the name of reverse func to Reverse to make it exportable to main package. Like below
package stringutil
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
A different problem with the same symptoms I ran into was that I was having two functions with the same name in Package B. Since two functions wih the same name but different types are no problem, I didn't think about it too much, however, VSCode didn't show the methods when I tried to use them in Package A, despite them being capitalized.
According to the question asked here
this is not supported by Go and requires you to change the function name or use introspection/an interface.
Thought I'd share it since googling brought me to this question here multiple times and it might be something other Go learners might run into as well...
Related
I'm new to the Go language and have a problem when I'm trying to run a simple project which contains two files, on Goland IDE.
The first file called main -
package main
import "fmt"
func main() {
card := list{0, add(0)}
cards := append(card, add(3))
cards = append(card, add(4))
for i, c := range cards {
fmt.Println(i, c)
}
}
func add(x int) int {
return x + 1
}
And the second file called list -
package main
type list []int
When I'm trying to use the second file from the first file (use list type) I get compilation failed and -
command-line-arguments
.\main.go:6:10: undefined: list
What have I missed?
Ok, I got it, the Package option should be chosen instead of the File option -
I was wondering if it was possible to not know a function name but call it anyway and get values from it. This lead me to the reflection package and I got pretty close but I’m not sure about the last step - if there is one. Again please forgive me if I am missing something obvious, this is my first attempt at doing anything in Go other than getting it setup.
Of course being a compiled language there is no need to iterate through things to find function names, I know them all, but this is something I want to see if it is possible… I’m playing and learning.
Below is the code. What I would really like to do is in the main line extract the values set in ModuleBoot() <“1.0012”, 23> and SomethingBoot() <“1.0000”, 10> but so far all as I can get is structure information. Perhaps that’s just the way it is but perhaps there is a step or change that can make it go the next step.
Hopefully I copied all the relevant code over correctly so it compiles as is:
// Using: go version go1.9.7 linux/amd64
=======================================
FILE: main.go
=======================================
package main
import (
"fmt"
"reflect"
"playing/modules/core"
)
func main() {
miType := reflect.TypeOf(core.ModuleInfo{})
fmt.Println("")
for i := 0; i < miType.NumMethod(); i++ {
method := miType.Method(i)
fmt.Println(method.Name)
in := make([]reflect.Value, method.Type.NumIn())
in[0] = reflect.ValueOf(core.ModuleInfo{})
//fmt.Println("Params in:", method.Type.NumIn(), "Params out:", method.Type.NumOut())
mi := method.Func.Call(in)
fmt.Println("mi:", mi)
fmt.Println("")
}
}
=======================================
FILE: playing/modules/core/something.go
=======================================
package core
func (mi ModuleInfo) SomethingBoot() ModuleInfo {
mi.Version = "1.0000"
mi.Priority = 10
return mi
}
=======================================
FILE: playing/modules/core/modules.go
=======================================
package core
type ModuleInfo struct {
Version string
Priority int
}
func (mi ModuleInfo) ModuleBoot() ModuleInfo {
mi.Version = "1.0012"
mi.Priority = 23
return mi
}
The output I got from this was:
Started delve with config "Debug"
SomethingBoot
mi: [<core.ModuleInfo Value>]
ModuleBoot
mi: [<core.ModuleInfo Value>]
delve closed with code 0
To get the return value as a ModuleInfo, get the underlying value of the first return value and type assert that interface value to ModuleInfo:
// mi has type core.ModuleInfo
mi := method.Func.Call(in)[0].Interface().(core.ModuleInfo)
Run it on the Playground.
You can cut some of the reflect code by type asserting the method to a function with the correct signature and calling that function directly:
for i := 0; i < miType.NumMethod(); i++ {
method := miType.Method(i).Func.Interface().(func(core.ModuleInfo) core.ModuleInfo)
mi := method(core.ModuleInfo{})
fmt.Println("Version", mi.Version)
fmt.Println("Priority", mi.Priority)
fmt.Println("")
}
Run it on the Playground
Go natively supports functions as values; you don't need reflection to do this.
In particular, if you make your two functions top-level functions (not specifically tied to a struct):
package core
type ModuleInfo struct { ... }
func SomethingBoot() ModuleInfo
func ModuleBoot() ModuleInfo
Then you can write a function that takes a function as a parameter:
func PrintVersion(func booter() core.ModuleInfo) {
mi := booter()
fmt.Printf("version %s\n", mi.Version)
}
And you can just pass the pre-existing functions as parameters:
PrintVersion(core.SomethingBoot)
PrintVersion(core.ModuleBoot)
Notice that there aren't parentheses after the function name: you are passing the function itself as a parameter, not calling the function and passing its return value.
I try to use golang deal with this problem 557. Reverse Words in a String III
my code as below:
import "fmt"
import ss "strings"
func reverseWords(s string) string {
words := ss.Split(s," ");
res := "";
for i:=0; i < len(words);i++{
curWord := ss.Split(words[i],"");
for j:=len(curWord)-1; j >= 0;j--{
res += curWord[j];
}
if(i!=len(words)-1){
res += " ";
}
}
return res;
}
func main(){
s := "Let's take LeetCode contest";
fmt.Println(reverseWords(s));
}
Everything is ok in my pc, it can pass compile at least.
However, when I submit in leetcode it tell me :
Line 67: undefined: strings in strings.Trim
I google this error but get nothing relevant info. As a beginner in golang, I need help. Everything will be appreciated.
You're importing strings under an alias:
import ss "strings"
That means that everywhere in that file, instead of referring to strings you must refer to ss, for example:
words := ss.Split(s," ")
If you use the default import:
import "strings"
Then you can refer to it as strings as normal.
Note that the currently accepted answer is wrong about two things: you can absolutely use the alias as you have it, you just have to refer to the package with the aliased name. It will not cause any issues if you use the name you gave it. Second, you absolutely do need to import the strings package - with or without an alias, your choice - if you want to refer to it.
On a completely unrelated side note, you should strongly consider running go fmt on your code, as it does not follow Go coding standards; for example, standard Go code omits the vast majority of semicolons. The code will work regardless, but you'll have an easier time getting help from other Go developers if your code is formatted the way everyone else is used to seeing it.
If you import strings package with different name then it will cause issue as it is used by the wrapper code to run the function completely.
No need to import strings package again. It will be added.
Just use it directly.
func reverseWords(s string) string {
words := strings.Split(s," ");
res := "";
for i:=0; i < len(words);i++{
curWord := strings.Split(words[i],"");
for j:=len(curWord)-1; j >= 0;j--{
res += curWord[j];
}
if(i!=len(words)-1){
res += " ";
}
}
return res;
}
When writing a Go library that needs to use random numbers, what is the best way to initialize and consume random numbers?
I know that the std way to do this in an application is:
import (
"math/rand"
"time"
)
// do the initial seeding in an init fn
func init() {
// set the global seed and use the global fns
rand.Seed(time.Now().UTC().UnixNano())
}
func main() {
fmt.Println(rand.Int())
fmt.Println(rand.Intn(200))
}
So when I'm writing library code (not in the main package), should I just do the same:
package libfoo
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
func AwesomeFoo() {
r := rand.Intn(1000)
// ...
}
The application using my library might also do its own random number seeding and use rand.Intn, so my question really is - is there any downside to having a library seed the random number generator and some app code (or another library) do so as well?
Also is there any issue with the library using the "global" rand.Intn or rand.Int or should a library create it's own private Rand object via rand.New(src) and use that instead?
I don't have any particular reason for thinking this is unsafe, but I know enough about crypto and PRNGs to know that it is easy to get something wrong if you don't know what you're doing.
For example, here's a simple library for the Knuth (Fisher-Yates) shuffle that needs randomness: https://gist.github.com/quux00/8258425
What's best really just depends on the type of application you're writing and the type of library you want to create. If we're not sure, we can get the most flexibility by using a form of dependency injection through Go interfaces.
Consider the following naive Monte Carlo integrator that takes advantage of the rand.Source interface:
package monte
import (
"math/rand"
)
const (
DEFAULT_STEPS = 100000
)
type Naive struct {
rand *rand.Rand
steps int
}
func NewNaive(source rand.Source) *Naive {
return &Naive{rand.New(source), DEFAULT_STEPS}
}
func (m *Naive) SetSteps(steps int) {
m.steps = steps
}
func (m *Naive) Integrate1D(fn func(float64) float64, a, b float64) float64 {
var sum float64
for i := 0; i < m.steps; i++ {
x := (b-a) * m.rand.Float64()
sum += fn(x)
}
return (b-a)*sum/float64(m.steps)
}
We can then use this package to calculate the value of pi:
func main() {
m := monte.NewNaive(rand.NewSource(200))
pi := 4*m.Integrate1D(func (t float64) float64 {
return math.Sqrt(1-t*t)
}, 0, 1)
fmt.Println(pi)
}
In this case, the quality of our algorithm's results depend on the type of pseudorandom number generator used, so we need to provide a way for users to swap out one generator for another. Here we've defined an opaque type that takes a random number source in its constructor. By having their random number generator satisfy the rand.Source interface, our application writer can then swap out random number generators as needed.
However, there are many cases where this is exactly what we don't want to do. Consider a random password or key generator. In that case, what we really want is a high entropy source of truly random data, so we should just use the crypto/rand package internally and hide the details from our application writers:
package keygen
import (
"crypto/rand"
"encoding/base32"
)
func GenKey() (string, error) {
b := make([]byte, 20)
if _, err := rand.Read(b); err != nil {
return "", err
}
enc := base32.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZ346789")
return enc.EncodeToString(b), nil
}
Hopefully that helps you make a decision. If the code is for your own applications or applications within a specific company rather than industry wide or public use, lean towards the library design that exposes the fewest internals and creates the fewest dependencies rather than the most general design, since that will ease maintenance and shorten implementation time.
Basically, if it feels like overkill, it probably is.
In the case of the Knuth Shuffle, the requirements are simply a decent psuedo-random number generator, so you could simply use an internally seeded rand.Rand object that's private to your package like so:
package shuffle
import (
"math/rand"
"time"
)
var r *rand.Rand
func init() {
r = rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
}
func ShuffleStrings(arr []string) {
last := len(arr)-1
for i := range arr {
j := r.Intn(last)
arr[i], arr[j] = arr[j], arr[i]
}
}
Then the application doesn't have to worry about how it works:
package main
import (
"shuffle"
"fmt"
)
func main() {
arr := []string{"a","set","of","words"}
fmt.Printf("Shuffling words: %v\n", arr)
for i := 0; i<10; i++ {
shuffle.ShuffleStrings(arr)
fmt.Printf("Shuffled words: %v\n", arr)
}
}
This prevents the application from accidentally reseeding the random number generator used by your package by calling rand.Seed.
Don't seed the global random number generator. That should be left to package main.
If you care what your seed is, you should create your own private Rand object. If you don't care, you can just use the global source.
If you care about your numbers actually being random, you should use crypto/rand instead of math/rand.
I want to have a key insensitive string as key.
Is it supported by the language or do I have to create it myself?
thank you
Edit: What I am looking for is a way to make it by default instead of having to remember to convert the keys every time I use the map.
Edit: My initial code actually still allowed map syntax and thus allowed the methods to be bypassed. This version is safer.
You can "derive" a type. In Go we just say declare. Then you define methods on your type. It just takes a very thin wrapper to provide the functionality you want. Note though, that you must call get and set with ordinary method call syntax. There is no way to keep the index syntax or optional ok result that built in maps have.
package main
import (
"fmt"
"strings"
)
type ciMap struct {
m map[string]bool
}
func newCiMap() ciMap {
return ciMap{m: make(map[string]bool)}
}
func (m ciMap) set(s string, b bool) {
m.m[strings.ToLower(s)] = b
}
func (m ciMap) get(s string) (b, ok bool) {
b, ok = m.m[strings.ToLower(s)]
return
}
func main() {
m := newCiMap()
m.set("key1", true)
m.set("kEy1", false)
k := "keY1"
b, _ := m.get(k)
fmt.Println(k, "value is", b)
}
Two possiblities:
Convert to uppercase/lowercase if you're input set is guaranteed to be restricted to only characters for which a conversion to uppercase/lowercase will yield correct results (may not be true for some Unicode characters)
Convert to Unicode fold case otherwise:
Use unicode.SimpleFold(rune) to convert a unicode rune to fold case. Obviously this is dramatically more expensive an operation than simple ASCII-style case mapping, but it is also more portable to other languages. See the source code for EqualsFold to see how this is used, including how to extract Unicode runes from your source string.
Obviously you'd abstract this functionality into a separate package instead of re-implementing it everywhere you use the map. This should go without saying, but then you never know.
Here is something more robust than just strings.ToLower, you can use
the golang.org/x/text/cases package. Example:
package main
import "golang.org/x/text/cases"
func main() {
s := cases.Fold().String("March")
println(s == "march")
}
If you want to use something from the standard library, I ran this test:
package main
import (
"strings"
"unicode"
)
func main() {
var (
lower, upper int
m = make(map[string]bool)
)
for n := '\u0080'; n <= '\u07FF'; n++ {
q, r := n, n
for {
q = unicode.SimpleFold(q)
if q == n { break }
for {
r = unicode.SimpleFold(r)
if r == n { break }
s, t := string(q), string(r)
if m[t + s] { continue }
if strings.ToLower(s) == strings.ToLower(t) { lower++ }
if strings.ToUpper(s) == strings.ToUpper(t) { upper++ }
m[s + t] = true
}
}
}
println(lower == 951, upper == 989)
}
So as can be seen, ToUpper is the marginally better choice.