从go程序中的其他文件访问对象

时间:2014-07-08 19:37:18

标签: go

Go has a fully functional example app with three files的goji微框架,main.go, models.go and middleware.go。我使用go get命令安装了框架

go get github.com/zenazn/goji

因此可以在我的GOPATH中提供示例应用程序,就像这样

src/github.com/zenazn/goji/example

如果我导航到/ example /并运行go run main.go,则会给出错误,指出main.go文件未访问middleware.gomodels.go中的对象文件,像这样

./main.go:39: undefined: PlainText
./main.go:47: undefined: SuperSecure
./main.go:73: undefined: Greets
./main.go:74: undefined: Greets
./main.go:85: undefined: Greet
./main.go:98: undefined: Greets
./main.go:99: undefined: Greets
./main.go:107: undefined: Users
./main.go:116: undefined: Greets
./main.go:116: too many errors

main.go中没有导入middleware.gomodels.go的代码,只有库的常规导入语句。

如何将这些文件捆绑在一起,以便另一个文件中的对象可用?

来自main.go

package main

import (
    "fmt"
    "io"
    "net/http"
    "regexp"
    "strconv"

    "github.com/zenazn/goji"
    "github.com/zenazn/goji/param"
    "github.com/zenazn/goji/web"
)

// Note: the code below cuts a lot of corners to make the example app simple.

func main() {
    // Add routes to the global handler
    goji.Get("/", Root)
    // Fully backwards compatible with net/http's Handlers
    goji.Get("/greets", http.RedirectHandler("/", 301))
    // Use your favorite HTTP verbs
    goji.Post("/greets", NewGreet)
    // Use Sinatra-style patterns in your URLs
    goji.Get("/users/:name", GetUser)
    // Goji also supports regular expressions with named capture groups.
    goji.Get(regexp.MustCompile(`^/greets/(?P<id>\d+)$`), GetGreet)

    // Middleware can be used to inject behavior into your app. The
    // middleware for this application are defined in middleware.go, but you
    // can put them wherever you like.
    goji.Use(PlainText)

    admin := web.New()
    goji.Handle("/admin/*", admin)
    admin.Use(SuperSecure)

    // Goji's routing, like Sinatra's, is exact: no effort is made to
    // normalize trailing slashes.
    goji.Get("/admin", http.RedirectHandler("/admin/", 301))


    admin.Get("/admin/", AdminRoot)
    admin.Get("/admin/finances", AdminFinances)

    // Use a custom 404 handler
    goji.NotFound(NotFound)

    goji.Serve()
}

middleware.go

package main

import (
    "encoding/base64"
    "net/http"
    "strings"

    "github.com/zenazn/goji/web"
)

// PlainText sets the content-type of responses to text/plain.
func PlainText(h http.Handler) http.Handler {
    fn := func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/plain")
        h.ServeHTTP(w, r)
    }
    return http.HandlerFunc(fn)
}

// Nobody will ever guess this!
const Password = "admin:admin"

// SuperSecure is HTTP Basic Auth middleware for super-secret admin page. Shhhh!
func SuperSecure(c *web.C, h http.Handler) http.Handler {
    fn := func(w http.ResponseWriter, r *http.Request) {
        auth := r.Header.Get("Authorization")
        if !strings.HasPrefix(auth, "Basic ") {
            pleaseAuth(w)
            return
        }

        password, err := base64.StdEncoding.DecodeString(auth[6:])
        if err != nil || string(password) != Password {
            pleaseAuth(w)
            return
        }

        h.ServeHTTP(w, r)
    }
    return http.HandlerFunc(fn)
}

func pleaseAuth(w http.ResponseWriter) {
    w.Header().Set("WWW-Authenticate", `Basic realm="Gritter"`)
    w.WriteHeader(http.StatusUnauthorized)
    w.Write([]byte("Go away!\n"))
}

models.go

package main

import (
    "fmt"
    "io"
    "time"
)

// A Greet is a 140-character micro-blogpost that has no resemblance whatsoever
// to the noise a bird makes.
type Greet struct {
    User    string    `param:"user"`
    Message string    `param:"message"`
    Time    time.Time `param:"time"`
}

// Store all our greets in a big list in memory, because, let's be honest, who's
// actually going to use a service that only allows you to post 140-character
// messages?
var Greets = []Greet{
    {"carl", "Welcome to Gritter!", time.Now()},
    {"alice", "Wanna know a secret?", time.Now()},
    {"bob", "Okay!", time.Now()},
    {"eve", "I'm listening...", time.Now()},
}

// Write out a representation of the greet
func (g Greet) Write(w io.Writer) {
    fmt.Fprintf(w, "%s\n@%s at %s\n---\n", g.Message, g.User,
        g.Time.Format(time.UnixDate))
}

// A User is a person. It may even be someone you know. Or a rabbit. Hard to say
// from here.
type User struct {
    Name, Bio string
}

// All the users we know about! There aren't very many...
var Users = map[string]User{
    "alice": {"Alice in Wonderland", "Eating mushrooms"},
    "bob":   {"Bob the Builder", "Making children dumber"},
    "carl":  {"Carl Jackson", "Duct tape aficionado"},
}

// Write out the user
func (u User) Write(w io.Writer, handle string) {
    fmt.Fprintf(w, "%s (@%s)\n%s\n", u.Name, handle, u.Bio)
}

2 个答案:

答案 0 :(得分:2)

只使用正在运行/正在编译main.go的go rungo run *.go,其他文件不包括在内。

答案 1 :(得分:0)

您最好使用go build - 来构建二进制文件,然后您可以将其作为./example运行。

Go对包而不是文件进行操作,而go run最终只是在测试示例或简单程序时使用它(它构建二进制文件并有效地丢弃它)。