mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
remove temprary function map parameter for gview when parsing template file and content
This commit is contained in:
@ -289,6 +289,10 @@ func (l *List) RemoveAll() {
|
||||
l.mu.Unlock()
|
||||
}
|
||||
|
||||
func (l *List) Clear() {
|
||||
l.RemoveAll()
|
||||
}
|
||||
|
||||
// 读锁操作
|
||||
func (l *List) RLockFunc(f func(list *list.List)) {
|
||||
l.mu.RLock()
|
||||
|
||||
@ -4,14 +4,18 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
// Package gqueue provides a dynamic/static concurrent-safe(alternative) queue.
|
||||
// Package gqueue provides a dynamic/static concurrent-safe queue.
|
||||
//
|
||||
// 并发安全动态队列.
|
||||
// Features:
|
||||
//
|
||||
// 1. FIFO queue(data -> list -> chan);
|
||||
//
|
||||
// 2. Fast creation and initialization;
|
||||
//
|
||||
// 3. Support dynamic queue size(unlimited queue size);
|
||||
//
|
||||
// 4. Blocking when reading data from queue;
|
||||
//
|
||||
// 特点:
|
||||
// 1. 动态队列初始化速度快;
|
||||
// 2. 动态的队列大小(不限大小);
|
||||
// 3. 取数据时如果队列为空那么会阻塞等待;
|
||||
package gqueue
|
||||
|
||||
import (
|
||||
@ -19,27 +23,21 @@ import (
|
||||
"math"
|
||||
)
|
||||
|
||||
// 1、这是一个先进先出的队列(chan <-- list);
|
||||
//
|
||||
// 2、当创建Queue对象时限定大小,那么等同于一个同步的chan并发安全队列;
|
||||
//
|
||||
// 3、不限制大小时,list链表用以存储数据,临时chan负责为客户端读取数据,当从chan获取数据时,list往chan中不停补充数据;
|
||||
//
|
||||
// 4、由于功能主体是chan,那么操作仍然像chan那样具有阻塞效果;
|
||||
type Queue struct {
|
||||
limit int // 队列限制大小
|
||||
list *glist.List // 底层数据链表
|
||||
events chan struct{} // 写入事件通知
|
||||
closed chan struct{} // 队列关闭通知
|
||||
C chan interface{} // 队列数据读取
|
||||
limit int // Limit for queue size.
|
||||
list *glist.List // Underlying list structure for data maintaining.
|
||||
events chan struct{} // Events for data writing.
|
||||
closed chan struct{} // Events for queue closing.
|
||||
C chan interface{} // Underlying channel for data reading.
|
||||
}
|
||||
|
||||
const (
|
||||
// 动态队列缓冲区大小
|
||||
// Size for queue buffer.
|
||||
gDEFAULT_QUEUE_SIZE = 10000
|
||||
)
|
||||
|
||||
// 队列大小为非必须参数,默认不限制
|
||||
// New returns a queue object.
|
||||
// Param <limit> is optional and it is not limited by default.
|
||||
func New(limit...int) *Queue {
|
||||
q := &Queue {
|
||||
closed : make(chan struct{}, 0),
|
||||
@ -56,7 +54,8 @@ func New(limit...int) *Queue {
|
||||
return q
|
||||
}
|
||||
|
||||
// 异步list->chan同步队列
|
||||
// startAsyncLoop starts an asynchronous goroutine,
|
||||
// which handles the data synchronization from list <q.list> to channel <q.C>.
|
||||
func (q *Queue) startAsyncLoop() {
|
||||
for {
|
||||
select {
|
||||
@ -84,7 +83,8 @@ func (q *Queue) startAsyncLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
// 将数据压入队列, 队尾
|
||||
// Push pushes the data <v> into the queue.
|
||||
// Note that it would panics if the Push method is called after the queue is closed.
|
||||
func (q *Queue) Push(v interface{}) {
|
||||
if q.limit > 0 {
|
||||
q.C <- v
|
||||
@ -94,19 +94,22 @@ func (q *Queue) Push(v interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// 从队头先进先出地从队列取出一项数据
|
||||
// Pop pops an item from the queue in FIFO way.
|
||||
// Note that it would return nil immediately if the Pop method is called after the queue is closed.
|
||||
func (q *Queue) Pop() interface{} {
|
||||
return <- q.C
|
||||
}
|
||||
|
||||
// 关闭队列(通知所有通过Pop*阻塞的协程退出)
|
||||
// Close closes the queue.
|
||||
// Notice: It would notify all goroutines exit immediately,
|
||||
// which are blocked reading by Pop method).
|
||||
func (q *Queue) Close() {
|
||||
close(q.C)
|
||||
close(q.events)
|
||||
close(q.closed)
|
||||
}
|
||||
|
||||
// 获取当前队列大小
|
||||
// Size returns the length of the queue.
|
||||
func (q *Queue) Size() int {
|
||||
return len(q.C) + q.list.Len()
|
||||
}
|
||||
|
||||
@ -295,4 +295,10 @@ func (set *Set) Sum() (sum int) {
|
||||
sum += gconv.Int(k)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Join joins items with a string <glue>.
|
||||
func (set *Set) Pops(size int) []interface{} {
|
||||
array := make([]interface{}, 0, size)
|
||||
return array
|
||||
}
|
||||
@ -18,7 +18,6 @@ type View struct {
|
||||
mu sync.RWMutex // 并发互斥锁
|
||||
view *gview.View // 底层视图对象
|
||||
data gview.Params // 视图数据/模板变量
|
||||
fmap gview.FuncMap // 绑定的模板函数
|
||||
response *ghttp.Response // 数据返回对象
|
||||
}
|
||||
|
||||
@ -27,7 +26,6 @@ func NewView(w *ghttp.Response) *View {
|
||||
return &View {
|
||||
view : gins.View(),
|
||||
data : make(gview.Params),
|
||||
fmap : make(gview.FuncMap),
|
||||
response : w,
|
||||
}
|
||||
}
|
||||
@ -48,18 +46,11 @@ func (view *View) Assign(key string, value interface{}) {
|
||||
view.mu.Unlock()
|
||||
}
|
||||
|
||||
// 绑定自定义模板函数
|
||||
func (view *View) BindFunc(name string, function interface{}){
|
||||
view.mu.Lock()
|
||||
view.fmap[name] = function
|
||||
view.mu.Unlock()
|
||||
}
|
||||
|
||||
// 解析模板,并返回解析后的内容
|
||||
func (view *View) Parse(file string) (string, error) {
|
||||
view.mu.RLock()
|
||||
defer view.mu.RUnlock()
|
||||
buffer, err := view.response.ParseTpl(file, view.data, view.fmap)
|
||||
buffer, err := view.response.ParseTpl(file, view.data)
|
||||
return buffer, err
|
||||
}
|
||||
|
||||
@ -67,7 +58,7 @@ func (view *View) Parse(file string) (string, error) {
|
||||
func (view *View) ParseContent(content string) (string, error) {
|
||||
view.mu.RLock()
|
||||
defer view.mu.RUnlock()
|
||||
buffer, err := view.response.ParseTplContent(content, view.data, view.fmap)
|
||||
buffer, err := view.response.ParseTplContent(content, view.data)
|
||||
return buffer, err
|
||||
}
|
||||
|
||||
|
||||
@ -13,13 +13,9 @@ import (
|
||||
)
|
||||
|
||||
// 展示模板,可以给定模板参数,及临时的自定义模板函数
|
||||
func (r *Response) WriteTpl(tpl string, params map[string]interface{}, funcMap...map[string]interface{}) error {
|
||||
fmap := make(gview.FuncMap)
|
||||
if len(funcMap) > 0 {
|
||||
fmap = funcMap[0]
|
||||
}
|
||||
if b, err := r.ParseTpl(tpl, params, fmap); err != nil {
|
||||
r.Write("Tpl Parsing Error: " + err.Error())
|
||||
func (r *Response) WriteTpl(tpl string, params...gview.Params) error {
|
||||
if b, err := r.ParseTpl(tpl, params...); err != nil {
|
||||
r.Write("Template Parsing Error: " + err.Error())
|
||||
return err
|
||||
} else {
|
||||
r.Write(b)
|
||||
@ -28,13 +24,9 @@ func (r *Response) WriteTpl(tpl string, params map[string]interface{}, funcMap..
|
||||
}
|
||||
|
||||
// 展示模板内容,可以给定模板参数,及临时的自定义模板函数
|
||||
func (r *Response) WriteTplContent(content string, params map[string]interface{}, funcMap...map[string]interface{}) error {
|
||||
fmap := make(gview.FuncMap)
|
||||
if len(funcMap) > 0 {
|
||||
fmap = funcMap[0]
|
||||
}
|
||||
if b, err := r.ParseTplContent(content, params, fmap); err != nil {
|
||||
r.Write("Tpl Parsing Error: " + err.Error())
|
||||
func (r *Response) WriteTplContent(content string, params...gview.Params) error {
|
||||
if b, err := r.ParseTplContent(content, params...); err != nil {
|
||||
r.Write("Template Parsing Error: " + err.Error())
|
||||
return err
|
||||
} else {
|
||||
r.Write(b)
|
||||
@ -43,61 +35,27 @@ func (r *Response) WriteTplContent(content string, params map[string]interface{}
|
||||
}
|
||||
|
||||
// 解析模板文件,并返回模板内容
|
||||
func (r *Response) ParseTpl(tpl string, params gview.Params, funcMap...map[string]interface{}) (string, error) {
|
||||
m := make(gview.FuncMap)
|
||||
if len(funcMap) > 0 {
|
||||
m = funcMap[0]
|
||||
}
|
||||
return gins.View().Parse(tpl, r.buildInVars(params), r.buildInFuncs(m))
|
||||
func (r *Response) ParseTpl(tpl string, params...gview.Params) (string, error) {
|
||||
return gins.View().Parse(tpl, r.buildInVars(params...))
|
||||
}
|
||||
|
||||
// 解析并返回模板内容
|
||||
func (r *Response) ParseTplContent(content string, params gview.Params, funcMap...map[string]interface{}) (string, error) {
|
||||
m := make(gview.FuncMap)
|
||||
if len(funcMap) > 0 {
|
||||
m = funcMap[0]
|
||||
}
|
||||
return gins.View().ParseContent(content, r.buildInVars(params), r.buildInFuncs(m))
|
||||
func (r *Response) ParseTplContent(content string, params...gview.Params) (string, error) {
|
||||
return gins.View().ParseContent(content, r.buildInVars(params...))
|
||||
}
|
||||
|
||||
// 内置变量
|
||||
func (r *Response) buildInVars(params map[string]interface{}) map[string]interface{} {
|
||||
if params == nil {
|
||||
params = make(map[string]interface{})
|
||||
}
|
||||
c := gins.Config()
|
||||
if c.GetFilePath() != "" {
|
||||
params["Config"] = c.GetMap("")
|
||||
// 内置变量/对象
|
||||
func (r *Response) buildInVars(params...map[string]interface{}) map[string]interface{} {
|
||||
vars := map[string]interface{}(nil)
|
||||
if len(params) > 0 {
|
||||
vars = params[0]
|
||||
} else {
|
||||
params["Config"] = nil
|
||||
vars = make(map[string]interface{})
|
||||
}
|
||||
params["Cookie"] = r.request.Cookie.Map()
|
||||
params["Session"] = r.request.Session.Data()
|
||||
return params
|
||||
}
|
||||
|
||||
// 内置函数
|
||||
func (r *Response) buildInFuncs(funcMap map[string]interface{}) map[string]interface{} {
|
||||
if funcMap == nil {
|
||||
funcMap = make(map[string]interface{})
|
||||
}
|
||||
funcMap["get"] = r.funcGet
|
||||
funcMap["post"] = r.funcPost
|
||||
funcMap["request"] = r.funcRequest
|
||||
return funcMap
|
||||
}
|
||||
|
||||
// 模板内置函数: get
|
||||
func (r *Response) funcGet(key string, def...string) string {
|
||||
return r.request.GetQueryString(key, def...)
|
||||
}
|
||||
|
||||
// 模板内置函数: post
|
||||
func (r *Response) funcPost(key string, def...string) string {
|
||||
return r.request.GetPostString(key, def...)
|
||||
}
|
||||
|
||||
// 模板内置函数: request
|
||||
func (r *Response) funcRequest(key string, def...string) string {
|
||||
return r.request.Get(key, def...)
|
||||
vars["Config"] = gins.Config().GetMap("")
|
||||
vars["Cookie"] = r.request.Cookie.Map()
|
||||
vars["Session"] = r.request.Session.Map()
|
||||
vars["Get"] = r.request.GetQueryMap()
|
||||
vars["Post"] = r.request.GetPostMap()
|
||||
return vars
|
||||
}
|
||||
@ -15,7 +15,8 @@ import (
|
||||
"github.com/gogf/gf/g/container/gtype"
|
||||
"github.com/gogf/gf/g/os/gcache"
|
||||
"github.com/gogf/gf/g/os/genv"
|
||||
"github.com/gogf/gf/g/os/glog"
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/os/glog"
|
||||
"github.com/gogf/gf/g/os/gproc"
|
||||
"github.com/gogf/gf/g/os/gtimer"
|
||||
"github.com/gogf/gf/g/text/gregex"
|
||||
@ -108,9 +109,9 @@ const (
|
||||
HOOK_BEFORE_OUTPUT = "BeforeOutput"
|
||||
HOOK_AFTER_OUTPUT = "AfterOutput"
|
||||
|
||||
// deprecated.
|
||||
// Deprecated.
|
||||
HOOK_BEFORE_CLOSE = "BeforeClose"
|
||||
// deprecated.
|
||||
// Deprecated.
|
||||
HOOK_AFTER_CLOSE = "AfterClose"
|
||||
|
||||
HTTP_METHODS = "GET,PUT,POST,DELETE,PATCH,HEAD,CONNECT,OPTIONS,TRACE"
|
||||
@ -188,10 +189,10 @@ func serverProcessInit() {
|
||||
go handleProcessMessage()
|
||||
}
|
||||
|
||||
// 是否处于开发环境
|
||||
//if gfile.MainPkgPath() != "" {
|
||||
// glog.Debug("GF notices that you're in develop environment, so error logs are auto enabled to stdout.")
|
||||
//}
|
||||
// 是否处于开发环境,这里调用该方法初始化main包路径值,
|
||||
// 防止异步服务goroutine获取main包路径失败,
|
||||
// 该方法只有在main协程中才会执行。
|
||||
gfile.MainPkgPath()
|
||||
}
|
||||
|
||||
// 获取/创建一个默认配置的HTTP Server(默认监听端口是80)
|
||||
|
||||
@ -69,7 +69,7 @@ func (s *Session) Id() string {
|
||||
}
|
||||
|
||||
// 获取当前session所有数据
|
||||
func (s *Session) Data() map[string]interface{} {
|
||||
func (s *Session) Map() map[string]interface{} {
|
||||
if len(s.id) > 0 || s.request.Cookie.GetSessionId() != "" {
|
||||
s.init()
|
||||
return s.data.Map()
|
||||
|
||||
@ -440,10 +440,14 @@ func homeWindows() (string, error) {
|
||||
// Available in develop environment.
|
||||
//
|
||||
// 获取入口函数文件所在目录(main包文件目录),
|
||||
// **仅对源码开发环境有效(即仅对生成该可执行文件的系统下有效)**
|
||||
// **仅对源码开发环境有效(即仅对生成该可执行文件的系统下有效)**。
|
||||
// 注意:该方法被第一次调用时,如果是在异步的goroutine中,该方法可能无法获取到main包路径。
|
||||
func MainPkgPath() string {
|
||||
path := mainPkgPath.Val()
|
||||
if path != "" {
|
||||
if path == "-" {
|
||||
return ""
|
||||
}
|
||||
return path
|
||||
}
|
||||
for i := 1; i < 10000; i++ {
|
||||
@ -457,6 +461,8 @@ func MainPkgPath() string {
|
||||
break
|
||||
}
|
||||
}
|
||||
// 找不到,下次不用再检索了
|
||||
mainPkgPath.Set("-")
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,8 @@ var (
|
||||
// if the template files under <path> changes (recursively).
|
||||
func (view *View) getTemplate(path string, pattern string) (tpl *template.Template, err error) {
|
||||
r := templates.GetOrSetFuncLock(path, func() interface {} {
|
||||
files, err := gfile.ScanDir(path, pattern, true)
|
||||
files := ([]string)(nil)
|
||||
files, err = gfile.ScanDir(path, pattern, true)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -90,7 +91,7 @@ func (view *View) searchFile(file string) (path string, folder string, err error
|
||||
// ParseContent parses given template file <file>
|
||||
// with given template parameters <params> and function map <funcMap>
|
||||
// and returns the parsed string content.
|
||||
func (view *View) Parse(file string, params map[string]interface{}, funcMap...map[string]interface{}) (parsed string, err error) {
|
||||
func (view *View) Parse(file string, params...Params) (parsed string, err error) {
|
||||
view.mu.RLock()
|
||||
defer view.mu.RUnlock()
|
||||
path, folder, err := view.searchFile(file)
|
||||
@ -101,9 +102,6 @@ func (view *View) Parse(file string, params map[string]interface{}, funcMap...ma
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(funcMap) > 0 {
|
||||
tpl = tpl.Funcs(funcMap[0])
|
||||
}
|
||||
tpl, err = tpl.Parse(gfcache.GetContents(path))
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -112,10 +110,16 @@ func (view *View) Parse(file string, params map[string]interface{}, funcMap...ma
|
||||
// of the existing <params> or view.data because both variables are pointers.
|
||||
// It's need to merge the values of the two maps into a new map.
|
||||
vars := (map[string]interface{})(nil)
|
||||
length := len(view.data)
|
||||
if len(params) > 0 {
|
||||
length += len(params[0])
|
||||
}
|
||||
if length > 0 {
|
||||
vars = make(map[string]interface{}, length)
|
||||
}
|
||||
if len(view.data) > 0 {
|
||||
if len(params) > 0 {
|
||||
vars = make(map[string]interface{}, len(view.data) + len(params))
|
||||
for k, v := range params {
|
||||
for k, v := range params[0] {
|
||||
vars[k] = v
|
||||
}
|
||||
for k, v := range view.data {
|
||||
@ -125,7 +129,9 @@ func (view *View) Parse(file string, params map[string]interface{}, funcMap...ma
|
||||
vars = view.data
|
||||
}
|
||||
} else {
|
||||
vars = params
|
||||
if len(params) > 0 {
|
||||
vars = params[0]
|
||||
}
|
||||
}
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if err := tpl.Execute(buffer, vars); err != nil {
|
||||
@ -137,13 +143,10 @@ func (view *View) Parse(file string, params map[string]interface{}, funcMap...ma
|
||||
// ParseContent parses given template content <content>
|
||||
// with given template parameters <params> and function map <funcMap>
|
||||
// and returns the parsed content in []byte.
|
||||
func (view *View) ParseContent(content string, params Params, funcMap...map[string]interface{}) (string, error) {
|
||||
func (view *View) ParseContent(content string, params...Params) (string, error) {
|
||||
view.mu.RLock()
|
||||
defer view.mu.RUnlock()
|
||||
tpl := template.New("").Delims(view.delimiters[0], view.delimiters[1]).Funcs(view.funcMap)
|
||||
if len(funcMap) > 0 {
|
||||
tpl = tpl.Funcs(funcMap[0])
|
||||
}
|
||||
tpl := template.New("template content").Delims(view.delimiters[0], view.delimiters[1]).Funcs(view.funcMap)
|
||||
tpl, err := tpl.Parse(content)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -152,10 +155,16 @@ func (view *View) ParseContent(content string, params Params, funcMap...map[stri
|
||||
// of the existing <params> or view.data because both variables are pointers.
|
||||
// It's need to merge the values of the two maps into a new map.
|
||||
vars := (map[string]interface{})(nil)
|
||||
length := len(view.data)
|
||||
if len(params) > 0 {
|
||||
length += len(params[0])
|
||||
}
|
||||
if length > 0 {
|
||||
vars = make(map[string]interface{}, length)
|
||||
}
|
||||
if len(view.data) > 0 {
|
||||
if len(params) > 0 {
|
||||
vars = make(map[string]interface{}, len(view.data) + len(params))
|
||||
for k, v := range params {
|
||||
for k, v := range params[0] {
|
||||
vars[k] = v
|
||||
}
|
||||
for k, v := range view.data {
|
||||
@ -165,7 +174,9 @@ func (view *View) ParseContent(content string, params Params, funcMap...map[stri
|
||||
vars = view.data
|
||||
}
|
||||
} else {
|
||||
vars = params
|
||||
if len(params) > 0 {
|
||||
vars = params[0]
|
||||
}
|
||||
}
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if err := tpl.Execute(buffer, vars); err != nil {
|
||||
|
||||
@ -62,7 +62,7 @@ func Export(i...interface{}) string {
|
||||
func PrintBacktrace() {
|
||||
index := 1
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
for i := 0; i < 10000; i++ {
|
||||
for i := 1; i < 10000; i++ {
|
||||
if _, path, line, ok := runtime.Caller(i); ok {
|
||||
buffer.WriteString(fmt.Sprintf(`%d. %s:%d%s`, index, path, line, "\n"))
|
||||
index++
|
||||
|
||||
@ -6,13 +6,12 @@ import (
|
||||
|
||||
func main() {
|
||||
s := ghttp.GetServer()
|
||||
s.EnableAdmin()
|
||||
s.BindHandler("/", func(r *ghttp.Request) {
|
||||
r.Response.Writeln("您可以同时通过HTTP和HTTPS方式看到该内容!")
|
||||
})
|
||||
s.EnableHTTPS("./server.crt", "./server.key")
|
||||
s.SetHTTPSPort(8198, 8199)
|
||||
s.SetPort(8200, 8300)
|
||||
s.SetHTTPSPort(8100, 8200)
|
||||
s.SetPort(8300, 8400)
|
||||
s.EnableAdmin()
|
||||
s.Run()
|
||||
}
|
||||
|
||||
16
geg/net/ghttp/server/template/build-in/objects/objects.go
Normal file
16
geg/net/ghttp/server/template/build-in/objects/objects.go
Normal file
@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/net/ghttp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := g.Server()
|
||||
s.BindHandler("/", func(r *ghttp.Request) {
|
||||
content := `{{.Request.Get "name"}}`
|
||||
r.Response.WriteTplContent(content)
|
||||
})
|
||||
s.SetPort(8199)
|
||||
s.Run()
|
||||
}
|
||||
@ -10,8 +10,13 @@ func main() {
|
||||
s.BindHandler("/", func(r *ghttp.Request) {
|
||||
r.Cookie.Set("theme", "default")
|
||||
r.Session.Set("name", "john")
|
||||
content := `Config:{{.Config.redis.cache}}, Cookie:{{.Cookie.theme}}, Session:{{.Session.name}}`
|
||||
r.Response.WriteTplContent(content, nil)
|
||||
content := `
|
||||
Get: {{.Get.name}}
|
||||
Post: {{.Post.name}}
|
||||
Config: {{.Config.redis}}
|
||||
Cookie: {{.Cookie.theme}},
|
||||
Session: {{.Session.name}}`
|
||||
r.Response.WriteTplContent(content)
|
||||
})
|
||||
s.SetPort(8199)
|
||||
s.Run()
|
||||
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/frame/gmvc"
|
||||
"github.com/gogf/gf/g/net/ghttp"
|
||||
)
|
||||
@ -11,7 +12,7 @@ type ControllerIndex struct {
|
||||
|
||||
func (c *ControllerIndex) Info() {
|
||||
c.View.Assign("title", "Go Frame 第一个网站")
|
||||
c.View.Assigns(map[string]interface{}{
|
||||
c.View.Assigns(g.Map{
|
||||
"name": "很开心1",
|
||||
"score": 100,
|
||||
})
|
||||
|
||||
@ -14,9 +14,6 @@ func main() {
|
||||
s.SetAccessLogEnabled(true)
|
||||
s.SetPort(2333)
|
||||
|
||||
v := g.View()
|
||||
v.AddPath("template")
|
||||
|
||||
s.BindHandler("/", func(r *ghttp.Request) {
|
||||
content, _ := gins.View().Parse("test.html", nil)
|
||||
r.Response.Write(content)
|
||||
|
||||
@ -2,14 +2,20 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/net/ghttp"
|
||||
"github.com/gogf/gf/g/frame/gmvc"
|
||||
)
|
||||
|
||||
|
||||
type Controller struct {
|
||||
gmvc.Controller
|
||||
}
|
||||
|
||||
func (c *Controller) Test() {
|
||||
c.View.Display("layout.html")
|
||||
}
|
||||
func main() {
|
||||
s := g.Server()
|
||||
s.BindHandler("/", func(r *ghttp.Request) {
|
||||
r.Response.WriteTpl("layout.html", nil)
|
||||
})
|
||||
s.BindControllerMethod("/", new(Controller), "Test")
|
||||
s.SetPort(8199)
|
||||
s.Run()
|
||||
}
|
||||
|
||||
@ -1,52 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g/container/gset"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 创建一个非并发安全的集合对象
|
||||
s := gset.New(true)
|
||||
|
||||
// 添加数据项
|
||||
s.Add(1)
|
||||
|
||||
// 批量添加数据项
|
||||
s.Add([]interface{}{1, 2, 3}...)
|
||||
|
||||
// 集合数据项大小
|
||||
fmt.Println(s.Size())
|
||||
|
||||
// 集合中是否存在指定数据项
|
||||
fmt.Println(s.Contains(2))
|
||||
|
||||
// 返回数据项slice
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// 删除数据项
|
||||
s.Remove(3)
|
||||
|
||||
// 遍历数据项
|
||||
s.Iterator(func(v interface{}) bool {
|
||||
fmt.Println("Iterator:", v)
|
||||
return true
|
||||
})
|
||||
|
||||
// 将集合转换为字符串
|
||||
fmt.Println(s.String())
|
||||
|
||||
// 并发安全写锁操作
|
||||
s.LockFunc(func(m map[interface{}]struct{}) {
|
||||
m[4] = struct{}{}
|
||||
})
|
||||
|
||||
// 并发安全读锁操作
|
||||
s.RLockFunc(func(m map[interface{}]struct{}) {
|
||||
fmt.Println(m)
|
||||
})
|
||||
|
||||
// 清空集合
|
||||
s.Clear()
|
||||
fmt.Println(s.Size())
|
||||
go func() {
|
||||
go func() {
|
||||
fmt.Println("main:", gfile.MainPkgPath())
|
||||
}()
|
||||
}()
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package gf
|
||||
|
||||
const VERSION = "v1.6.4"
|
||||
const VERSION = "v1.6.5"
|
||||
const AUTHORS = "john<john@goframe.org>"
|
||||
|
||||
Reference in New Issue
Block a user