go語言問題集錦

==============================================beego框架===========================================html

1.使用beego框架上傳文件前端

問題描述:文件上傳失敗,出現The filename, directory name, or volume label syntax is incorrectweb

問題分析:在上傳文件時,爲了不文件名重複帶來的文件覆蓋問題,使用時間對文件進行重命名。時間格式:YYYY-MM-DD HH:mm:ss。當文件路徑中出現冒號是,會出現上述錯誤。算法

解決方法:去掉文件中的冒號,文件名改用YYYY-MM-DD-HH-mm-ss格式,問題解決後端

 

2.beegoweb開發頁面日期顯示格式問題數組

問題描述:在web開發時,常常會從後臺讀取數據到前端顯示,可是有時候日期的格式並不是咱們想要的格式安全

解決方法:beego提供了日期顯示時的格式化方法:cookie

{{.Atime.Format "2006-01-02 15:04:05"}}

3.後端獲取的列表在前端頁面顯示的方法session

問題描述:web開發時,常常須要從後臺查詢獲取數據列表,那麼數據列表在表單如何遍歷顯示呢數據結構

解決方法:beego提供了range能夠遍歷後臺傳遞的數據列表

{{range .aticles}}
                <tr>
                    <td>{{.Aname}}</td><!--Aname是articles的屬性字段-->
                    <td><a href="/content?id={{.Id}}">查看詳情</a></td>
                    <td> {{.Atime.Format "2006-01-02 15:04:05"}}</td>
                    <td>{{.Acount}}</td>
                    <td><a href="/delete?id={{.Id}}" class="dels">刪除</a></td>
                    <td><a href="/update?id={{.Id}}">編輯</a></td>
                    <td>財經新聞</td>
                </tr>

{{end}}

4.視圖函數

問題描述:在web中,常常會遇到簡單的數據運算,如分頁場景,點擊上一頁,須要當前頁減1運算。在beego中,不支持前端運算。

解決方法:beego框架提供了視圖函數,解決前端運算的需求。

1.首先在main.go程序中添加視圖函數,並將視圖函數和key進行關聯

func main() {
	beego.AddFuncMap("showprePage", showprePage)
	beego.AddFuncMap("shownextPage", shownextPage)
	beego.Run()
}

//定義視圖函數
func showprePage(pageIndex int) (preIndex int) {
	preIndex = pageIndex - 1
	return
}

func shownextPage(pageIndex int) (nextIndex int) {
	nextIndex = pageIndex + 1
	return
}

2.在前端引用視圖函數,使用管道|引用

<a href="/index?pageIndex={{.pageIndex|showprePage}}">上一頁 </a>

  說明:|前的是函數的參數,整個運算的結果就是最終的返回結果

5.beego框架下的分頁

問題描述:在web開發中,常常遇到分頁的功能

解決方法:下面介紹一下beego框架實現分頁的方法

1.後臺獲取總記錄數

o := orm.NewOrm()

//獲取總數量
count, err := o.QueryTable("Article").Count()
if err != nil {
	beego.Info("獲取總數量出錯", err)
} 

2.後臺計算總頁數

pageSize := 2                                          //每頁的大小 ,一般從前端傳入
pages := math.Ceil(float64(count) / float64(pageSize)) //獲取總頁數,並向上取整

3.查詢分頁的部分數據

start := (pageIndex - 1) * pageSize  //計算起始的位置(當前頁-1)*頁大小
var articles []models.Article
_, err = o.QueryTable("Article").Limit(pageSize, start).All(&articles)  //Limit  第一個參數:頁大小,  第二個參數:起始位置

4.前端利用視圖函數,實現上一頁、下一頁的計算,並將當前頁經過url拼接形式傳入後臺

<li> <a href="/index?pageIndex={{.pageIndex|showprePage}}">上一頁 </a> </li>
<li> <a href="/index?pageIndex={{.pageIndex|shownextPage}}">下一頁</a></li>

5.後臺對當前頁進行處理,即超過總頁數或小於等於0的狀況

if pageIndex <= 0 {
	pageIndex = 1
}
if pageIndex > int(pages) {
	pageIndex = int(pages)
}

6.beego中cookie和session的使用

6.1 beego利用Cookie實現記住用戶名

 實現思路:

在用戶登陸時,若是點擊  記住用戶名,在後臺處理登陸時,獲取remember是否爲on

若是是,則將用戶名信息設置到cookie中:

if remember == "on" {
	c.Ctx.SetCookie("userName", userName, 200) //設置cookie,200s過時
} else {
	c.Ctx.SetCookie("userName", userName, -1) //設置cookie,-1表示cookie當即失效
}

在進入登陸頁面時,從cookie中獲取用戶名,若是有值,則跳轉到登陸頁面時將用戶名信息返回到前臺,同時返回  記住用戶名選中:

userName := c.Ctx.GetCookie("userName")
beego.Info("用戶名:", userName)
if userName != "" {
	c.Data["userName"] = userName
	c.Data["checked"] = "checked"
}
c.TplName = "login.html"

6.2.beego利用session實現用戶狀態的判斷

 實現思路:

首先在app.conf配置文件中開啓session: sessionon=true

在用戶登陸成功後,將用戶名信息設置到session中

c.SetSession("userName", userName) //設置session,判斷用戶登陸的狀態
c.Redirect("/index", 302) 

用戶跳轉到主頁以前,須要判斷session中是否有值,若是沒有則跳轉到登陸頁面:

userName := c.GetSession("userName")
if userName == nil { //若是用戶未登陸,跳轉到登陸頁面
	c.Redirect("/login", 302)
	return
}

6.3.beego利用session實現用戶信息的顯示和退出登陸

 用戶信息顯示:

用戶登陸成功後,將用戶名信息放入session中,而後跳轉到主頁時再將session信息傳入前端:

userName := c.GetSession("userName")
c.Data["userName"] = userName

 退出登陸:

在處理退出登陸的方法中,刪除對應的session就能夠了,而後在跳轉到登陸頁面:

func (c *MainController) Logout() {
	c.DelSession("userName")
	c.Redirect("/login", 302)
}

==============================================go語言基礎===========================================  

1.go語言中切片的複製和擴容問題

go語言中,能夠經過截取切片來產生新的切片,可是產生的新切片和原來的切片共享同一底層數組

如:

// 建立一個整型切片
// 其長度和容量都是 5 個元素
myNum := []int{10, 20, 30, 40, 50}
// 建立一個新切片
// 其長度爲 2 個元素,容量爲 4 個元素
newNum := slice[1:3]

執行上面的代碼後,咱們有了兩個切片,它們共享同一段底層數組,但經過不一樣的切片會看到底層數組的不一樣部分:

 

若是經過append函數增長切片的新元素,若是沒有超過切片的容量,那麼新切片和原切片仍然共享一塊內存。若是超過了容量,則會產生一個新的底層數組:

若是切片的底層數組沒有足夠的可用容量,append() 函數會建立一個新的底層數組,將被引用的現有的值複製到新數組裏,再追加新的值,此時 append 操做同時增長切片的長度和容量:

如:

myNum := []int{10, 20, 30, 40, 50}
// 建立新的切片,其長度爲 2 個元素,容量爲 4 個元素
newNum := myNum[1:3]
// 使用原有的容量來分配一個新元素
// 將新元素賦值爲 60
newNum = append(newNum, 60)

執行上面的代碼後的底層數據結構以下圖所示:

此時由於 newNum 在底層數組裏還有額外的容量可用,append() 函數將可用的元素合併入切片的長度,並對其進行賦值。因爲和原始的切片共享同一個底層數組,myNum 中索引爲 3 的元素的值也被改動了。

 

// 建立一個長度和容量都是 4 的整型切片
myNum := []int{10, 20, 30, 40}
// 向切片追加一個新元素
// 將新元素賦值爲 50
newNum := append(myNum, 50)

當這個 append 操做完成後,newSlice 擁有一個全新的底層數組,這個數組的容量是原來的兩倍:

函數 append() 會智能地處理底層數組的容量增加。在切片的容量小於 1000 個元素時,老是會成倍地增長容量。一旦元素個數超過 1000,容量的增加因子會設爲 1.25,也就是會每次增長 25%的容量(隨着語言的演化,這種增加算法可能會有所改變)。

注意:

內置函數 append() 在操做切片時會首先使用可用容量。一旦沒有可用容量,就會分配一個新的底層數組。這致使很容易忘記切片間正在共享同一個底層數組。一旦發生這種狀況,對切片進行修改,極可能會致使隨機且奇怪的問題,這種問題通常都很難調查。若是在建立切片時設置切片的容量和長度同樣,就能夠強制讓新切片的第一個 append 操做建立新的底層數組,與原有的底層數組分離。這樣就能夠安全地進行後續的修改操做了:

myFruit := fruit[2:3:3]
// 向 myFruit 追加新字符串
myFruit = append(myFruit, "Kiwi")

這裏,咱們限制了 myFruit 的容量爲 1。當咱們第一次對 myFruit 調用 append() 函數的時候,會建立一個新的底層數組,這個數組包括 2 個元素,並將水果 Plum 複製進來,再追加新水果 Kiwi,並返回一個引用了這個底層數組的新切片。由於新的切片 myFruit 擁有了本身的底層數組,因此杜絕了可能發生的問題。咱們能夠繼續向新切片裏追加水果,而不用擔憂會不當心修改了其餘切片裏的水果。能夠經過下圖來理解此時內存中的數據結構:

相關文章
相關標籤/搜索