main程序跑起来报错

Go
请问一下,在go1.15.6中运行该代码,会提示报错undefined:NewURLStore是为什么呢,代码都是跟着教程上面走的, 而且全部复制粘贴也还是会报错。

讨论数量: 4

我猜,前边的定义没有一起贴下来吧

type URLStore struct {

    urls map[string]string    // map 是从短网址到长网址

    mu    sync.RWMutex

}
func (s *URLStore) Get(key string) string {

    s.mu.RLock()

    defer s.mu.RUnlock()

    return s.urls[key]

}

func (s *URLStore) Set(key, url string) bool {

    s.mu.Lock()

    defer s.mu.Unlock()

    _, present := s.urls[key]

    if present {

        return false

    }

    s.urls[key] = url

    return true

}

func NewURLStore() *URLStore {

    return &URLStore{ urls: make(map[string]string) }

}
3年前 评论
lawrencepu (楼主) 3年前
wj2015 (作者) 3年前
lawrencepu (楼主) 3年前

store.go:


import "sync"

type URLStore struct {
    urls map[string]string
    mu   sync.RWMutex
}

func NewURLStore() *URLStore {
    return &URLStore{urls: make(map[string]string)}
}

func (s *URLStore) Get(key string) string {
    s.mu.RLock()
    defer s.mu.RUnlock()
    return s.urls[key]
}

func (s *URLStore) Set(key, url string) bool {
    s.mu.Lock()
    defer s.mu.Unlock()
    if _, present := s.urls[key]; present {
        return false
    }
    s.urls[key] = url
    return true
}

func (s *URLStore) Count() int {
    s.mu.RLock()
    defer s.mu.RUnlock()
    return len(s.urls)
}

func (s *URLStore) Put(url string) string {
    for {
        key := genKey(s.Count()) // generate the short URL
        if ok := s.Set(key, url); ok {
            return key
        }
    }
    // shouldn't get here
    return ""
}

main.go:

package main

import (
    "fmt"
    "net/http"
)

const AddForm = `
<form method="POST" action="/add">
URL: <input type="text" name="url">
<input type="submit" value="Add">
</form>
`

var store = NewURLStore()

func main() {
    http.HandleFunc("/", Redirect)
    http.HandleFunc("/add", Add)
    http.ListenAndServe(":8080", nil)
}

func Redirect(w http.ResponseWriter, r *http.Request) {
    key := r.URL.Path[1:]
    url := store.Get(key)
    if url == "" {
        http.NotFound(w, r)
        return
    }
    http.Redirect(w, r, url, http.StatusFound)
}

func Add(w http.ResponseWriter, r *http.Request) {
    url := r.FormValue("url")
    if url == "" {
        w.Header().Set("Content-Type", "text/html")
        fmt.Fprint(w, AddForm)
        return
    }
    key := store.Put(url)
    fmt.Fprintf(w, "http://localhost:8080/%s", key)
}

key.go:

package main

var keyChar = []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

func genKey(n int) string {
    if n == 0 {
        return string(keyChar[0])
    }
    l := len(keyChar)
    s := make([]byte, 20) // FIXME: will overflow. eventually.
    i := len(s)
    for n > 0 && i >= 0 {
        i--
        j := n % l
        n = (n - j) / l
        s[i] = keyChar[j]
    }
    return string(s[i:])
}

@wj2015 我自己敲的试了不行我就直接贴代码,最后还是不行

3年前 评论

运行方式貌似不大对。。。

方式一:通过goland中main函数边的三角来运行,如图:

file
file

方式二:go build

会在当前目录下编译一个可执行文件,我用的windows环境,所以是exe文件,然后执行该文件可以启动服务。

file

方式三:go run .\main.go .\store.go .\key.go
linux or macos下可以用go run *.go

file

运行结果:

file

3年前 评论
lawrencepu (楼主) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!