我在golang中构建自己的路由器以理解逻辑,但是我发现404错误没有找到正常,我能够运行到服务器但是我用 hello 名称编写了函数,它没有运行。这可能是什么原因?
package main
import (
"fmt"
"log"
"net/http"
"strings"
"time"
)
var Session *http.Server
var r Router
func Run(port string) {
Session = &http.Server{
Addr: port,
Handler: &r,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(Session.ListenAndServe())
}
type Handle func(http.ResponseWriter, *http.Request)
type Router struct {
mux map[string]Handle
}
func newRouter() *Router {
return &Router{
mux: make(map[string]Handle),
}
}
func (r *Router) Add(path string, handle Handle) {
r.mux[path] = handle
}
func GetHeader(url string) string {
sl := strings.Split(url, "/")
return fmt.Sprintf("/%s", sl[1])
}
func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
head := GetHeader(r.URL.Path)
h, ok := rt.mux[head]
if ok {
h(w, r)
return
}
http.NotFound(w, r)
}
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%s", "hello world")
}
func main() {
r := newRouter()
r.Add("/hello", hello)
Run(":8080")
}
答案 0 :(得分:5)
您的主要功能是使用<!doctype html><html>
<head>
<meta http-equiv=""X-UA-Compatible"" content=""IE=edge""/>
</head><body>
<style>
.video-container {
position:relative;
padding-bottom:56.25%;
padding-top:30px;
height:0;
overflow:hidden;
}
.video-container iframe, .video-container object, .video-container embed {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
}
}
</style>
<div class="video-container">
<div id="player"></div>
</div>
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
width: '640',
height: '390',
videoId: 'jhFDyDgMVUI',
playerVars: { autohide: 1, showinfo: 0 , html5: 1, enablejsapi: 1, autoplay: 1, origin: 'http://www.example.co'},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
alert('apirdy');
}
function onPlayerReady(event) {
event.target.playVideo();
alert('onrdy');
player.addEventListener('onStateChange', onPlayerStateChange);
}
function onPlayerStateChange(event) {
alert('onchange');
}
</script>
</body></html>
表示法,声明并初始化一个名为r的新局部变量,其范围与您在列表顶部的全局变量不同。
这意味着您要添加处理程序的:=
变量不是您尝试分配给r
结构的全局变量,因此您的Http.Server
根本找不到任何映射到它自己的接收器ServeHTTP
。
解决方案是将r
声明为指向r Router
的指针,如下所示:
Router
并且在你的处理程序中,你可以直接传递指针而不需要任何解除引用:
var r *Router
当然,请记住通过指定指针值来初始化变量,而不是声明一个新的本地变量:
Session = &http.Server{
Addr: port,
Handler: r,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
答案 1 :(得分:0)
你有全局变量var r Router
但是在func main()
内你创建了另一个,本地变量和路径恰好只添加到它:
func main() {
r := newRouter()
r.Add("/hello", hello)
Run(":8080")
}
只需调整
即可var r =&Router{}
func Run(port string) {
Session = &http.Server{
Addr: port,
Handler: r,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(Session.ListenAndServe())
}
func main() {
r = newRouter()
r.Add("/hello", hello)
Run(":8080")
}