Go語言基礎學習五-一些數值操作的簡單例子

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

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章