Go 的路由规则较为简单,可以分为两种类型:以 / 结尾的 pattern 和不以 / 结尾的 pattern。
/ 的路由规则例如:
handle("/user", userhandler)此时,客户端访问路径 uri 必须与 /user 完全匹配(如 https://*****/user),路由才会匹配到 /user 定义的 handler。
/ 的路由规则例如:
handle("/user/", userhandler)客户端访问 https://*****/user/ 或 https://*****/user/**** 都会匹配到 /user/ 定义的 handler。
实际上,即使客户端访问 https://*****/user,也可能匹配到 /user/ 对应的 handler,具体情况后续会解析。
handle("/", roothandler)
handle("/user", userhandler)在这种情况下:
https://*****/user 时,路由会匹配到 /user 对应的 handler -> userhandler。https://*****/user/ 时,路由会匹配到 / 对应的 handler -> roothandler。https://*****/user/*** 时,路由仍会匹配到 / 对应的 handler -> roothandler。/user 和 /user/**** 都匹配同一个 userhandler可以通过以下方式实现:
handle("/user", userhandler)
handle("/user/", userhandler)handle("/", userhandler)/ 的路由规则handle("/user/", userhandler)表面上看,第一种和第三种方法似乎重复,但其中有细微区别,具体解析如下:
如果定义了:
handle("/", roothandler)
handle("/user/", userhandler)此时,当访问 http://****/user 时,路由匹配不到 /user 定义的 handler 时,也不会进入 / 定义的路由规则。Go 服务器会返回一个 301 Moved Permanently 重定向,跳转到 /user/。
简单来说,如果找不到 /user 对应的 handler,Go 会自动尝试在 /user/ 查找。如果找到了 /user/ 的路由规则,Go 将返回一个重定向响应,指示客户端重定向到 /user/。详细代码可参考 ServeMux 的 Handler 方法实现。
从性能角度来看,直接注册 handle("/user", userhandler),这样完全匹配 /user 的方式效率较高,它避免了额外的重定向开销。