How to use other struct methods from other files in Golang - go

I have a file called login.go and account.go
In login.go
func (api *ApiResource) test() {
fmt.Println("Works!")
}
In account.go I have:
func main () {
Res := new(ApiResource)
Res.test()
}
Buit I'm getting undefined:test error.
They both use package main and are on same src/ folder
What do I need to fix here?

If you used go run then you must pass both files to like go run login.go account.go.

Related

how to generate or change code in compile time?

I want to add some code to start of function.
like
source code:
func A(){
do something...
}
final code:
func A(){
ADDED CODE
do something...
}
I`m using //go:generate right now,but it will change the source code and should run it every function changed,so I wonder if there any way to do the job in compile time
What about using a function call to add code?
package mypkg
var extra = func() {}
func A() {
extra()
// ...do something
}
Then you can include or exclude an extra file to the same package:
package mypkg
func init() {
extra = func() {
// ADDED CODE
}
}
You even could select from one ore more files with alternatives for the extra() function.
[H]ow to generate or change code in compile time?
You have to modify the compiler. (Don't do that.)

Problems running binary created by Go build

I have a simple Go application, it has a few template files where I render some text. After I build my binary with Go build I try to run the file and I get the error:
panic: html/template: pattern matches no files: public/*.html
I am using the Echo framework and have followed their steps on adding a render for templates.
Here is the code in my main.go file
// TemplateRenderer is a custom html/template renderer for Echo framework
type TemplateRenderer struct {
templates *template.Template
}
// Render renders a template document
func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
func main() {
// Create a new instance of Echo
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
renderer := &TemplateRenderer{
templates: template.Must(template.ParseGlob("public/*.html")),
}
e.Renderer = renderer
e.GET("/", func(context echo.Context) error {
return context.Render(http.StatusOK, "index.html", api.FetchCoinList())
})
}
Is there something I have to do to package my templates up in the binary? It works perfectly when I run go run main.go
Is there something I have to do to package my templates up in the binary?
Yes, make them avialable at the same (relative) folder where they are present when you run them with go run main.go.
For example if there is a public folder containing the templates next to your main.go, then make sure you "copy" the public folder next to your executable binary.
Read this question+answer for more options: how to reference a relative file from code and tests
Usually you should provide ways to define where to get static assets and files from. The app may have a default place to look for them, but it should be easy to change this setting (e.g. via command line flags, via environment variables or via config files).
Another option is to include static files in the executable binary. Check out this question how to do that: What's the best way to bundle static resources in a Go program?

golang : Custom package and 'undefined'

I've read the doc on creating custom packages, etc but I can't seem to pin down what the problem is.
GOPATH=/Users/lrsmith/GoWorkSpace
|->bin
|->pkg
|->src
|->github.com
|->lrsmith
|-> zaphod
|-> zaphod.go
I've done a 'go get github.com/lrsmith/go-icinga2-api/iapi' and it
dropped it into the same dir as 'zaphod' and created and .a file under pkg.
GOPATH=/Users/lrsmith/GoWorkSpace
|->bin/
|->pkg/
|->..../iapi.a
|->src/
|->github.com/
|->lrsmith/
|-> zaphod/
|-> zaphod.go
|-> go-icinga2-api/
zaphod.go is very simple right now
package main
import (
"github.com/lrsmith/go-icinga2-api/iapi"
)
func main () {
t := iapi.Config("zaphod","beeblebrox","http://localhost",true)
}
When I do a go build in the zaphod directory I get
./zaphod.go:11: undefined: iapi.Config
I've read through the docs, checked cases and tried different structures but I can't seem to get it to load the package and let me call iapi.Config. The iapi code works and if I build something in the go-icinga2-api directory it works fine and the test all pass.
I want to create a separate project/code base that imports the go-icinga2-api and uses it, but can't seem to get it work.
Thanks
Len
Added info. The structure for go-icinga2-api is
go-icinga2-api
|-> iapi
|-> client.go
|-> client_test.go
|-> host.go
.......
client.go is
// Package iapi provides a client for interacting with an Icinga2 Server
package iapi
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"net/http"
)
// Server ... Use to be ClientConfig
type Server struct {
Username string
Password string
BaseURL string
AllowUnverifiedSSL bool
httpClient *http.Client
}
// func Config ...
func (server *Server) Config(username, password, url string, allowUnverifiedSSL bool) (*Server, error) {
// TODO : Add code to verify parameters
return &Server{username, password, url, allowUnverifiedSSL, nil}, nil
}
I've tried with the .go files up one level, i.e. not nested underneath iapi/ to for the same results.
Updated Answer
In client.go, it looks like you're trying to use Config as a constructor for Server structs. Since Config is defined with a receiver (func (server *Server)), it's a method of Server and can't be called directly. You're code should work if you remove (server *Server).
It's idiomatic to name constructors New[type being returned], or New if the type is the same name as the package.
From the 3rd paragraph of the Package Names section of Idiomatic Go:
the function to make new instances of ring.Ring—which is the definition of a constructor in Go—would normally be called NewRing, but since Ring is the only type exported by the package, and since the package is called ring, it's called just New, which clients of the package see as ring.New
Original Answer
The import path should reference a directory. In your code, you then reference that package by whatever name is used in the package [name] in the .go files in that directory.
For example, if github.com/lrsmith/go-icinga2-api contains a file called api.go with the line package iapi, your importing package should look like this:
package main
import (
"github.com/lrsmith/go-icinga2-api"
)
func main () {
t := iapi.Config("zaphod","beeblebrox","http://localhost",true)
}
Note the declaration of the Config() function:
func (server *Server) Config(username, password, url string, allowUnverifiedSSL bool) (*Server, error)
It's a "method" that should be applied to a Server object:
server.Config(...)
Thus you need to first create a Server object (or you could try with nil):
var server iapi.Server
server, err := server.Config(...)
You're trying to run it as if it had the following declaration:
func Config(username, password, url string, allowUnverifiedSSL bool) (*Server, error)

Package is found but contents are not?

I get a strange error while building my go project.
My structure:
-$GOPATH
-src
-main
-main.go
-configuration
-configuration.go
configuration.go:
package configuration;
type Config int;
func (c Config) Parse(s string) map[string]string {...}
main.go
package main;
import"configuration"
func main() {
var config Config;
argMap := config.parse(...);
return;
}
if my working directory is $GOPATH, I do:
go build configuration - no output, OK
go build main
imported and not used "configuration"
undefined: Config
So my package is found ($GOPATH/pkg contains configuration.go with correct content - I can see the Parse method) and main imports it, but does not recognize its contents?
I recon the problem is that the type Config is not exported? Why would that be?
You are trying to use Config from package main, where it is not defined, instead of the one from configuration (thats the error "imported and not used"):
package main
import "configuration"
func main() {
var config configuration.Config
argMap := config.Parse(...)
}
The second problem is calling unexported parse instead of Parse as explained by VonC.
argMap := config.parse(...); wouldn't work, since you declared a Parse() method.
(as in "exported method configuration.Parse()")
var config configuration.Config
argMap := config.Parse(...);
Config is exported, but the methods are case-sensitive (cf. Exported Identifiers).

Can't use struct from own package

I created following file structure in $GOPATH/src
bitbucket.org/MyName/ProjectName
I have follwoing files here
ProjectName
- controllers/
- meController.go
- app.go
In app.go I'm importing my controller like that:
import "bitbucket.org/MyName/ProjectName/controllers"
And in main func I'm trying to use it's method.
meController = new(controllers.meController)
m.Get("/", meController.Index)
My meController.go looks like this
package controllers
type meController struct {
}
func (controller *meController) Index () string {
return "Hello World"
}
But I'm getting this error:
./app.go:5: imported and not used: "bitbucket.org/MyName/ProjectName/controllers"
./app.go:12: undefined: meController
I don't have any idea how to get this to work.
Any ideas?
Thanks!
In Go, every symbol that starts with lowercase is not exported by the package. call your struct MeController and you'll be fine.

Resources