Go語言基礎學習5-一些數值操作的簡單例子
實現一個網頁,在網頁上具有數值統計的功能。該數值統計的功能主要是1.將切片排序 2.計算切片的平均數 3.計算切片的中位數
我們先大致知道這個例子我們需要學到的知識如下:
1.如何創建一個簡單的服務器,訪問路徑時如何調用函數。//入口
2.如何解析網頁的請求和輸入數據。//請求
3.如何直接向網頁寫入html操作頁面,響應返回。//響應
4.處理數值的一些操作:格式化輸入輸出,字符串替換,字符串到數值的轉換,根據空格將字符串轉換爲切片,切片內數據的添加,切片排序操作,結構體的使用,for range的使用
step1:定義統計結果結構體
type statistics struct{
numbers []float64
mean float64
median float64
}
step2:定義統計函數
function getStats(numbers []float64) (stat statistics){
//先將number進行排序
stat.numbers = numbers
sort.Float64s(stat.numbers)//調用sort包排序函數
//計算切片平均數,這裏切片長度需要轉化成float64類型以便運算
stat.mean = sum(numbers)/float64(len(numbers))
//計算切片中位數,sum,median均爲實現函數,這裏就不貼相關代碼了
stat.median = median(numbers)
}
接下來進入到web頁面的實現,實現一個簡單的http服務器。
主函數如下:
fun main(){
http.HandleFunc(“/”,homepage)//該函數有兩個參數,一個是路徑,一個是當這個路徑被請求時會被執行的函數的引用,這個函數的簽名必須是func(http.Response,*http.Request)我們可以註冊多個路徑-函數對,這裏我們只註冊了”/”(通常爲主頁)
if err:=http.ListenAdServe(“:9001”.nil);err!=nill{
//http.ListenAndServe()函數使用給定的Tcp地址啓動一個web服務器。這裏我們使用localhost:9001(只給端口不給網絡地址默認爲 localhost),第二個參數表示支持自定義服務器,爲空則表示使用默認類型
log.Fatal(“failed to start server”,err )
}
}
部分常量值
const (
pageTop = `<!DOCTYPE HTML><html><head>
<style>.error{color:#FF0000;}</style></head><title>Statistics</title>
<body><h3>Statistics</h3>
<p>Computes basic statistics for a given list of numbers</p>`
form = `<form action="/" method="POST">
<label for="numbers">Numbers (comma or space-separated):</label><br />
<input type="text" name="numbers" size="30"><br />
<input type="submit" value="Calculate">
</form>`
pageBottom = `</body></html>`
anError = `<p class="error">%s</p>`//用於格式化輸出
)
接下來分析homePage()函數,這個函數在“/”路徑被訪問時會被調用
//homePage的簽名形式必須如下func(http.Response,*http.Request)
func homePage(writer http.ResponseWriter, request *http.Request) {
//第一步解析表單,在寫響應內容前調用
err := request.ParseForm() // Must be called before writing response
//分析完表單後,將pageTop和form兩個字符串寫入客戶端,
fmt.Fprint(writer, pageTop, form)
//若分析表單失敗,寫入錯誤信息anError,err是被格式化的值
if err != nil {
fmt.Fprintf(writer, anError, err)
} else {
//分析表單成功後,則processRequest函數解析請求數據,將輸入轉化爲切片格式
if numbers, message, ok := processRequest(request); ok {
//轉換切片成功後,調用getStat進行統計運算,將運算後的結果stat轉換成格式化的html字符串寫入客戶端
stats := getStats(numbers)
fmt.Fprint(writer, formatStats(stats))
} else if message != "" {
//轉換切片失敗則輸出錯誤信息
fmt.Fprintf(writer, anError, message)
//fmt.Fprintf(writer,format,value)屬於格式化輸出,將value以format格式輸出
}
}
fmt.Fprint(writer, pageBottom)
}
//這裏就是請求數據處理的部分
func processRequest(request *http.Request) ([]float64, string, bool) {
var numbers []float64
//首先獲取請求表單中標籤名爲numbers的輸入
if slice, found := request.Form["numbers"]; found && len(slice) > 0 {
//標籤存在並且輸入不爲空則將改輸入字符串中所有逗號替換爲空格,-1(替換次數)表示替換所有
text := strings.Replace(slice[0], ",", " ", -1)
for _, field := range strings.Fields(text) {
//將替換後的字符串text根據空格轉換成切片並遍歷切片數據,將切片中的每個數據轉換成float64位
if x, err := strconv.ParseFloat(field, 64); err != nil {
return numbers, "'" + field + "' is invalid", false
} else {
//將float64數值添加到numbers切片中返回
numbers = append(numbers, x)
}
}
}
if len(numbers) == 0 {
return numbers, "", false // no data first time form is shown
}
return numbers, "", true
}