一铣鹏、數(shù)據(jù)類型轉(zhuǎn)換
https://studygolang.com/articles/10838
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"fmt"
"strconv"
)
func main() {
//int到string
str := strconv.Itoa(int(1))
fmt.Println("int轉(zhuǎn)string", str)
//int64到string
str2 := strconv.FormatInt(int64(1), 10)
fmt.Println("int64轉(zhuǎn)string", str2)
//float64轉(zhuǎn)string formatFloat只能接收float64如果想用float32需要強轉(zhuǎn)float64(float32(0.8))
//下面是參數(shù)說明
// 'b' (-ddddp±ddd,二進制指數(shù))
// 'e' (-d.dddde±dd,十進制指數(shù))
// 'E' (-d.ddddE±dd闺金,十進制指數(shù))
// 'f' (-ddd.dddd,沒有指數(shù))
// 'g' ('e':大指數(shù)毡代,'f':其它情況)
// 'G' ('E':大指數(shù)辜妓,'f':其它情況)
str3 := strconv.FormatFloat(float64(0.8), 'f', -1, 32)
fmt.Println("float32轉(zhuǎn)string", str3)
//string到int 有異常的都不進行處理這個后面說
i, _ := strconv.Atoi("10")
fmt.Println("strin轉(zhuǎn)int", i)
//string 到int64
i64, _ := strconv.ParseInt("123", 10, 64)
fmt.Println("strin轉(zhuǎn)int64", i64)
//string轉(zhuǎn)float64 如果想轉(zhuǎn)float32 用float32(fl32)強轉(zhuǎn)一下就可以
fl32, _ := strconv.ParseFloat("3.1415926535", 32/64)
fmt.Println("strin轉(zhuǎn)float64", fl32)
}
</pre>
二、時間類型轉(zhuǎn)換
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"fmt"
"time"
)
func main() {
//獲取當前時間
now := time.Now()
//時間轉(zhuǎn)化為string
//在go語言里將日期格式化并不是yyyy-MM-dd HH:ss:mm 而是用"2006-01-02 15:04:05具體含義如下
//月份 1,01,Jan,January
//日 2,02,_2
//時 3,03,15,PM,pm,AM,am
//分 4,04
//秒 5,05
//年 06,2006
//周幾 Mon,Monday
//時區(qū)時差表示 -07,-0700,Z0700,Z07:00,-07:00,MST
//時區(qū)字母縮寫 MST
timeStr := now.Format("2006-01-02 15:04:05")
fmt.Println("日期類型當前時間: ", now)
fmt.Println("字符串類型當前時間: ", timeStr)
//string轉(zhuǎn)化為時間
date, _ := time.Parse("2006-01-02 15:04:05", "2017-08-29 08:37:18")
fmt.Println("string轉(zhuǎn)日期:", date)
//判斷兩個時間先后
trueOrFalse := date.After(now)
if trueOrFalse == true {
fmt.Println("2017-08-29 08:37:18在", timeStr, "之后")
} else {
fmt.Println("2017-08-29 08:37:18在", timeStr, "之前")
}
// ParseDuration parses a duration string.
// A duration string is a possibly signed sequence of decimal numbers,
// each with optional fraction and a unit suffix,
// such as "300ms", "-1.5h" or "2h45m".
// Valid time units are "ns", "us" (or "μs"), "ms", "s", "m", "h".
// -代表時間之前,不加代表時間之后 m表示分鐘,如20分鐘前
m, _ := time.ParseDuration("-20m")
m1 := now.Add(m)
fmt.Println("10分鐘之前:", m1)
// h代表小時 一天之前為-24h
h, _ := time.ParseDuration("-8h")
h1 := now.Add(h)
fmt.Println("8小時之前", h1)
// // 一天前
d, _ := time.ParseDuration("-24h")
d1 := now.Add(d)
fmt.Println(d1)
//計算兩個時間差幾秒
sec := now.Sub(m1)
fmt.Println(sec.Seconds(), "秒")
//計算兩個時間差幾分鐘
minutes := now.Sub(m1)
fmt.Println(minutes.Minutes(), "分鐘")
//計算兩個時間差幾小時
hours := now.Sub(h1)
fmt.Println(hours.Hours(), "小時")
//計算兩個時間差幾天
day := now.Sub(d1)
fmt.Println(day.Hours()/24, "天")
//注意:splite3數(shù)據(jù)庫中字段如果是datetime類型獲取數(shù)據(jù)時格式轉(zhuǎn)換會有問題
//如2017-08-29 08:37:18這樣的時間從數(shù)據(jù)庫獲取后會變成2017-08-29T08:37:18Z
//進行格式轉(zhuǎn)化之后不能比較碌宴,所以需要將T和Z替換為" "
//不知道其他數(shù)據(jù)庫有沒有這樣的問題
}
</pre>
三杀狡、配置文件讀取
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"flag"
"sync"
"github.com/larspensjo/config"
)
var Conf_Main_Topic = "DEFAULT"
var (
//config.ini為配置文件格式為 key=value
configFile = flag.String("configfile", "config.ini", "General configuration file")
)
var commonConf = make(map[string]string)
var lock sync.RWMutex
func LoadCommonConfiguration() {
lock.Lock()
defer lock.Unlock()
cfg, err := config.ReadDefault(*configFile)
if err != nil {
//....
}
commonConf = make(map[string]string)
if cfg.HasSection(Conf_Main_Topic) {
section, err := cfg.SectionOptions(Conf_Main_Topic)
if err != nil {
//....
}
for _, v := range section {
options, err := cfg.String(Conf_Main_Topic, v)
if err != nil {
//....
}
commonConf[v] = options
}
}
}
//通過GetConf方法將key傳入獲取value值
func GetConf(key string) string {
lock.RLock()
defer lock.RUnlock()
return commonConf[key]
}
</pre>
四、Json與Map轉(zhuǎn)換
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"encoding/json"
"strings"
// "github.com/bitly/go-simplejson" // for json get
)
//把兩層嵌套結(jié)構(gòu)的json格式的數(shù)據(jù)組轉(zhuǎn)成map(map中不含interface結(jié)構(gòu))
func NoInterfaceJsonToMap(input string) (map[string]map[string]interface{}, error) {
result := make(map[string]map[string]interface{})
err := json.Unmarshal([]byte(input), &result)
if err != nil {
return nil, err
}
return result, nil
}
func MapToJson(input map[string]interface{}) (string, error) {
result, err := json.Marshal(input)
if err != nil {
// panic(err)
return "", err
}
return string(result), nil
}
func MapMapToJson(input map[string]map[string]interface{}) (string, error) {
result, err := json.Marshal(input)
if err != nil {
return "", err
}
return string(result), nil
}
func JsonToMap(input string) (map[string]interface{}, error) {
result := make(map[string]interface{})
err := json.Unmarshal([]byte(input), &result)
if err != nil {
return nil, err
}
return result, nil
}
func BoltKeyValueToJson(key, value string, delimeter string) (string, error) {
keys := []string{key}
values := []string{value}
return BoltKeyValuesToJson(keys, values, delimeter)
}
func BoltKeyValuesToJson(keys, values []string, delimeter string) (string, error) {
mapResult := make(map[string]interface{})
for i := range keys {
key := strings.Split(keys[i], delimeter)
value := values[i]
cur := mapResult
for j := range key {
if j == len(key)-1 {
} else if j == len(key)-2 {
if cur[key[j]] == nil {
cur[key[j]] = map[string]string{key[len(key)-1]: value}
} else {
cur[key[j]].(map[string]string)[key[len(key)-1]] = value
}
} else {
if cur[key[j]] == nil {
cur[key[j]] = make(map[string]interface{})
}
cur = cur[key[j]].(map[string]interface{})
}
}
}
return MapToJson(mapResult)
}
</pre>
五贰镣、通過JSON數(shù)據(jù)發(fā)送Email
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"strings"
)
func HttpPostByJSON(accessUrl string, json string, redo int) error {
fmt.Println(json)
fmt.Println("post write json bytes:" + strconv.Itoa(len(json)))
for j := 1; j <= redo; j++ {
req_new := bytes.NewBuffer([]byte(json))
request, err := http.NewRequest("POST", accessUrl, req_new)
if err == nil {
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
client := http.Client{}
response, err1 := client.Do(request)
if err1 == nil {
body, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Println("Unknown error in sending Email")
} else {
resp := string(body)
if strings.Contains(resp, ""code":"200"") {
return nil
} else {
fmt.Println(string(body))
}
}
} else {
fmt.Println(err1)
}
} else {
fmt.Println(err)
}
}
return errors.New("Fail to send email notification")
}
</pre>
六呜象、文件讀寫刪除操作
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
func FileExist(filename string) bool {
_, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
fmt.Println(err)
return err == nil || os.IsExist(err)
}
func ReadFileByLine(filename string) []string {
if !FileExist(filename) {
return []string{}
}
f, err := os.Open(filename)
fmt.Println(err)
defer f.Close()
rd := bufio.NewReader(f)
result := []string{}
for {
line, err := rd.ReadString('\n')
if err == nil || io.EOF == err {
line = strings.TrimSpace(line)
if len(line) > 0 {
result = append(result, line)
}
}
if io.EOF == err {
break
}
fmt.Println(err)
}
return result
}
func WriteFileByLine(filename string, data []string) {
f, err := os.Create(filename)
fmt.Println(err)
defer f.Close()
wt := bufio.NewWriter(f)
for i := range data {
_, err := wt.WriteString(data[i])
if io.EOF == err {
break
}
fmt.Println(err)
}
wt.Flush()
}
func DeleteFile(filename string) {
if FileExist(filename) {
err := os.Remove(filename)
fmt.Println(err)
}
}</pre>
七、go執(zhí)行l(wèi)inux和windows命令操作
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"errors"
"fmt"
"os/exec"
"runtime"
"strings"
)
func runInLinux(cmd string) string {
fmt.Println("Running Linux Cmd:" + cmd)
result, err := exec.Command("/bin/sh", "-c", cmd).Output()
if err != nil {
fmt.Println(err.Error())
}
return strings.TrimSpace(string(result))
}
func runInWindows(cmd string) string {
fmt.Println("Running Win Cmd:" + cmd)
result, err := exec.Command("cmd", "/c", cmd).Output()
if err != nil {
fmt.Println(err.Error())
}
return strings.TrimSpace(string(result))
}
func RunCommand(cmd string) string {
if runtime.GOOS == "windows" {
return runInWindows(cmd)
} else {
return runInLinux(cmd)
}
}
func RunLinuxCommand(cmd string) string {
if runtime.GOOS == "windows" {
return ""
} else {
return runInLinux(cmd)
}
}
func runInLinuxWithErr(cmd string) (string, error) {
fmt.Println("Running Linux Cmd:" + cmd)
result, err := exec.Command("/bin/sh", "-c", cmd).Output()
if err != nil {
fmt.Println(err.Error())
}
return strings.TrimSpace(string(result)), err
}
func runInWindowsWithErr(cmd string) (string, error) {
fmt.Println("Running Win Cmd:" + cmd)
result, err := exec.Command("cmd", "/c", cmd).Output()
if err != nil {
fmt.Println(err.Error())
}
return strings.TrimSpace(string(result)), err
}
func RunCommandWithErr(cmd string) (string, error) {
if runtime.GOOS == "windows" {
return runInWindowsWithErr(cmd)
} else {
return runInLinuxWithErr(cmd)
}
}
func RunLinuxCommandWithErr(cmd string) (string, error) {
if runtime.GOOS == "windows" {
return "", errors.New("could not run in windows OS")
} else {
return runInLinuxWithErr(cmd)
}
}</pre>
八碑隆、異常處理
Golang 有2個內(nèi)置的函數(shù) panic() 和 recover()恭陡,用以報告和捕獲運行時發(fā)生的程序錯誤,與 error 不同上煤,panic-recover 一般用在函數(shù)內(nèi)部子姜。一定要注意不要濫用 panic-recover,可能會導致性能問題楼入,我一般只在未知輸入和不可靠請求時使用。
golang 的錯誤處理流程:當一個函數(shù)在執(zhí)行過程中出現(xiàn)了異衬脸椋或遇到 panic()嘉熊,正常語句就會立即終止,然后執(zhí)行 defer 語句扬舒,再報告異常信息阐肤,最后退出 goroutine。如果在 defer 中使用了 recover() 函數(shù),則會捕獲錯誤信息,使該錯誤信息終止報告孕惜。
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"log"
"strconv"
)
//捕獲因未知輸入導致的程序異常
func catch(nums ...int) int {
defer func() {
if r := recover(); r != nil {
log.Println("[E]", r)
}
}()
return nums[1] * nums[2] * nums[3] //index out of range
}
//主動拋出 panic愧薛,不推薦使用,可能會導致性能問題
func toFloat64(num string) (float64, error) {
defer func() {
if r := recover(); r != nil {
log.Println("[W]", r)
}
}()
if num == "" {
panic("param is null") //主動拋出 panic
}
return strconv.ParseFloat(num, 10)
}
func main() {
catch(2, 8)
toFloat64("")
}</pre>
上面為引用的內(nèi)容原文地址http://www.jb51.net/article/58139.htm
go語言有異常的返回會有兩個返回參數(shù)包括值跟error衫画,判斷error是否為nil進行相應處理就可以最好不要panic
九毫炉、defer(延遲語句)
defer語句會在函數(shù)返回前,從后到前的依次執(zhí)行defer
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"fmt"
)
func main() {
fmt.Println("start================")
fmt.Println("t5返回值", t5())
fmt.Println("end================")
}
func t1() {
fmt.Println("t1")
}
func t2() {
fmt.Println("t2")
}
func t3() {
fmt.Println("t3")
}
func t4() {
fmt.Println("t4")
}
func t5() int {
defer t1()
defer t2()
defer t3()
defer t4()
return 1
}</pre>
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">程序輸出:
start================
t4
t3
t2
t1
t5返回值 1
end================</pre>
十削罩、數(shù)據(jù)庫操作
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"database/sql"
"errors"
"fmt"
"sync"
_ "github.com/mattn/go-sqlite3"
)
var db *sql.DB
var dbLock sync.Mutex
func main() {
//查詢調(diào)用RunQuery或者RunQueryWithErr
//?為占位符對應相應參數(shù)
rows := RunQuery("select age from table where id = ? and name = ?", 1, "abc")
//也可以使用struct構(gòu)建對象,獲取數(shù)據(jù)庫字段時需要用sql.Null...否則取空值會報錯
var age sql.NullInt64
var ages []Int64
//如果有多條返回值用for循環(huán)遍歷,如果確定只有一條可以用if,這里只有一條所以用if,也可以將if改為for
if rows.Next() {
err := rows.Scan(&age)
if err != nil {
//........
}
//sql.NullInt64中有兩個方法Int64和Valid,Valid用來判斷值是否為空返回值為true瞄勾、false
//Int64為實際值,sql.NullInt64對象如果為空Int64值為0
if age.Valid {
//對獲取到的age做操作
fmt.Println(age.Int64)
}
}
//sqlite3中使用完rows之后一定要調(diào)用close釋放鎖,否則繼續(xù)調(diào)用數(shù)據(jù)庫語句會報數(shù)據(jù)庫被鎖的異常
rows.Close()
//sqlite3中查詢和增刪改不能同時進行,也會報數(shù)據(jù)庫被鎖的異常
//需要在查詢之后統(tǒng)一進行增刪改操作,增刪改調(diào)用ExecSQL或ExecSqlWithErr
}
func OpenDB() {
var err error
//foo.db為數(shù)據(jù)庫名字
db, err = sql.Open("sqlite3", "./foo.db?_txlock=exclusive")
fmt.Println(err)
_, err = db.Exec("PRAGMA synchronous = OFF;")
fmt.Println(err)
}
func CloseDB() {
if db != nil {
err := db.Close()
db = nil
fmt.Println(err)
}
}
func ExecSQL(query string, args ...interface{}) sql.Result {
dbLock.Lock()
defer dbLock.Unlock()
if db == nil {
OpenDB()
}
if query == "" {
panic("Empty sql input")
}
fmt.Println("Running Exec:")
fmt.Println(query)
fmt.Println(args...)
res, err := db.Exec(query, args...)
fmt.Println(err)
return res
}
func RunQuery(query string, args ...interface{}) *sql.Rows {
dbLock.Lock()
defer dbLock.Unlock()
if db == nil {
OpenDB()
}
if query == "" {
panic("Empty sql input")
}
fmt.Println("Running Query:")
fmt.Println(query)
fmt.Println(args...)
res, err := db.Query(query, args...)
fmt.Println(err)
return res
}
//多條語句的事物操作
func ExecTransaction(querys []string, args [][]string) {
dbLock.Lock()
defer dbLock.Unlock()
if db == nil {
OpenDB()
}
tx, err := db.Begin()
fmt.Println(err)
fmt.Println("Running Trans:")
for index, query := range querys {
if query == "" {
panic("Empty sql input")
}
oldArgs := args[index]
newArgs := make([]interface{}, len(oldArgs))
for i, v := range oldArgs {
newArgs[i] = interface{}(v)
}
fmt.Println(query)
fmt.Println(newArgs...)
_, err := tx.Exec(query, newArgs...)
fmt.Println(err)
}
err = tx.Commit()
fmt.Println(err)
}
func OpenDBWithErr() error {
var err error
db, err = sql.Open("sqlite3", "./pjm.db?_txlock=exclusive")
if err != nil {
return err
}
_, err = db.Exec("PRAGMA synchronous = OFF;")
return err
}
func CloseDBWithErr() error {
if db != nil {
err := db.Close()
db = nil
return err
}
return nil
}
func ExecSQLWithErr(query string, args ...interface{}) (sql.Result, error) {
dbLock.Lock()
defer dbLock.Unlock()
if db == nil {
err := OpenDBWithErr()
if err != nil {
return nil, err
}
}
if query == "" {
return nil, errors.New("Empty sql input")
}
fmt.Println("Running Exec With Err:")
fmt.Println(query)
fmt.Println(args...)
return db.Exec(query, args...)
}
func RunQueryWithErr(query string, args ...interface{}) (*sql.Rows, error) {
dbLock.Lock()
defer dbLock.Unlock()
if db == nil {
err := OpenDBWithErr()
if err != nil {
return nil, err
}
}
if query == "" {
return nil, errors.New("Empty sql input")
}
fmt.Println("Running Query With Err:")
fmt.Println(query)
fmt.Println(args...)
return db.Query(query, args...)
}
func ExecTransactionWithErr(querys []string, args [][]string) error {
dbLock.Lock()
defer dbLock.Unlock()
if db == nil {
err := OpenDBWithErr()
if err != nil {
return err
}
}
tx, err := db.Begin()
if err != nil {
return err
}
fmt.Println("Running Trans With Err:")
for index, query := range querys {
if query == "" {
return errors.New("Empty sql input")
}
oldArgs := args[index]
newArgs := make([]interface{}, len(oldArgs))
for i, v := range oldArgs {
newArgs[i] = interface{}(v)
}
fmt.Println(query)
fmt.Println(newArgs...)
_, err := tx.Exec(query, newArgs...)
if err != nil {
return err
}
}
return tx.Commit()
}
</pre>
十一、go語言web編程
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">package main
import (
"fmt"
"html/template"
"log"
"net/http"
"strings"
)
func sayhelloName(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //解析url傳遞的參數(shù)弥激,對于POST則解析響應包的主體(request body)
//注意:如果沒有調(diào)用ParseForm方法进陡,下面無法獲取表單的數(shù)據(jù)
fmt.Println(r.Form) //這些信息是輸出到服務器端的打印信息
fmt.Println("path", r.URL.Path)
fmt.Println("scheme", r.URL.Scheme)
fmt.Println(r.Form["url_long"])
for k, v := range r.Form {
fmt.Println("key:", k)
fmt.Println("val:", strings.Join(v, ""))
}
fmt.Fprintf(w, "Hello astaxie!") //這個寫入到w的是輸出到客戶端的
}
func login(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method) //獲取請求的方法
//Handler里面是不會自動解析form的,必須顯式的調(diào)用r.ParseForm()后微服,才能對這個表單數(shù)據(jù)進行操作
r.ParseForm()
if r.Method == "GET" {
t, _ := template.ParseFiles("login.html")
t.Execute(w, nil)
} else {
//請求的是登陸數(shù)據(jù)趾疚,那么執(zhí)行登陸的邏輯判斷
fmt.Println("username:", r.Form["username"])
fmt.Println("password:", r.Form["password"])
//獲取username的值需要[0]
if r.Form["username"][0] == "abc" {
//如果username為abc跳轉(zhuǎn)到user.html頁面打印abc=====
t, _ := template.ParseFiles("./user.html")
//t.Execute第二個參數(shù)可以傳各種類型的數(shù)據(jù)到頁面
t.Execute(w, "abc=====")
} else if r.Form["username"][0] == "efg" {
t, _ := template.ParseFiles("./userMap.html")
result := map[string]string{}
result["key"] = "value"
//返回map
t.Execute(w, result)
} else {
t, _ := template.ParseFiles("./userMaps.html")
result := []map[string]string{}
m1 := map[string]string{}
m2 := map[string]string{}
m3 := map[string]string{}
m1["a1"] = "111"
m1["a2"] = "222"
m1["a3"] = "333"
m1["a4"] = "444"
m2["a1"] = "555"
m2["a2"] = "666"
m2["a3"] = "777"
m2["a4"] = "888"
m3["a1"] = "999"
m3["a2"] = "123"
m3["a3"] = "456"
m3["a4"] = "789"
result = append(result, m1, m2, m3)
//返回多個map
t.Execute(w, result)
}
}
}
func main() {
http.HandleFunc("/", sayhelloName) //設置訪問的路由
http.HandleFunc("/login", login) //設置訪問的路由
err := http.ListenAndServe(":9090", nil) //設置監(jiān)聽的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
</pre>
login.html頁面
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;"><html>
<head>
<title></title>
</head>
<body>
<form action="/login" method="post">
用戶名:<input type="text" name="username">
密碼:<input type="password" name="password">
<input type="submit" value="登陸">
</form>
</body>
</html>
</pre>
user.html頁面
go語言中頁面獲取值必須加{{ }}
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;"><html>
<head>
<title></title>
</head>
<body>
從后臺獲取的值為: {{.}}
</body>
</html>
</pre>
userMap.html頁面
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;"><html>
<head>
<title></title>
</head>
<body>
從后臺獲取的值為: {{.key}}
</body>
</html>
</pre>
userMaps.html頁面
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;"><html>
<head>
<title></title>
</head>
<body>
{{range re :=.}}
{{re.a2}}</br>
{{re.a4}}</br>
{{end}}
</body>
</html>
</pre>
十二、分頁實現(xiàn)
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;">//分頁方法以蕴,根據(jù)傳遞過來的頁數(shù)糙麦,每頁數(shù),總數(shù)舒裤,返回分頁的內(nèi)容 7個頁數(shù) 前 1喳资,2,3腾供,4仆邓,5 后 的格式返回,小于5頁返回具體頁數(shù)
func Paginator(page, prepage int, nums int64) map[string]interface{} {
var firstpage int //前一頁地址
var lastpage int //后一頁地址
//根據(jù)nums總數(shù),和prepage每頁數(shù)量 生成分頁總數(shù)
totalpages := int(math.Ceil(float64(nums) / float64(prepage))) //page總數(shù)
if page > totalpages {
page = totalpages
}
if page <= 0 {
page = 1
}
var pages []int
switch {
case page >= totalpages-5 && totalpages > 5: //最后5頁
start := totalpages - 5 + 1
firstpage = page - 1
lastpage = int(math.Min(float64(totalpages), float64(page+1)))
pages = make([]int, 5)
for i, _ := range pages {
pages[i] = start + i
}
case page >= 3 && totalpages > 5:
start := page - 3 + 1
pages = make([]int, 5)
firstpage = page - 3
for i, _ := range pages {
pages[i] = start + i
}
firstpage = page - 1
lastpage = page + 1
default:
pages = make([]int, int(math.Min(5, float64(totalpages))))
for i, _ := range pages {
pages[i] = i + 1
}
firstpage = int(math.Max(float64(1), float64(page-1)))
lastpage = page + 1
//fmt.Println(pages)
}
paginatorMap := make(map[string]interface{})
paginatorMap["pages"] = pages
paginatorMap["totalpages"] = totalpages
paginatorMap["firstpage"] = firstpage
paginatorMap["lastpage"] = lastpage
paginatorMap["currpage"] = page
return paginatorMap
}
</pre>
html頁面
<pre name="code" class="java" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; display: block; padding: 10px; margin: 0px 0px 10.5px; line-height: 1.42857; word-break: break-all; overflow-wrap: break-word; color: rgb(51, 51, 51); background-color: rgb(245, 245, 245); border: 1px solid rgb(204, 204, 204); border-radius: 0px;"> <div class="am-cf">
共{{.totals}}條記錄 共記{{.paginator.totalpages}} 頁 當前頁 {{.paginator.currpage}}
<div class="am-fr">
<ul class="am-pagination">
<li class=""><a href="/clubadmin/topics/{{.paginator.firstpage}}">?</a></li>
{{range page := .paginator.pages}}
<li {{if eq page }}class="am-active"{{end}}><a href="/clubadmin/topics/{{
page}}</a></li>
{{end}}
<li><a href="/clubadmin/topics/{{.paginator.lastpage}}">?</a></li>
</ul>
</div>
</div></pre>