大约两周前,我开始了高丽的开发,最近完成了推荐的入门书。
我现在正在学习Gophercises --一种通过小项目来提高初学者对Golang的理解的练习集。
这是我对第一个项目的解决方案:编写一个测试(cli-)应用程序。
要求很简单:
以下是我解决这个问题的方法:
package main
import (
"bufio"
"encoding/csv"
"flag"
"fmt"
"io"
"log"
"os"
)
type q struct {
question, answer string
}
func (q q) ask() bool {
fmt.Println(q.question, " equals: ")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
if scanner.Err() != nil {
log.Fatal(scanner.Err())
}
if scanner.Text() == q.answer {
return true
}
return false
}
func quizLoop(path string, verbose bool) {
// Loop should:
// 1. Read records line by line
// 2. Ask the question (i/o)
// 3. Keep score.
file, err := os.Open(path)
correct, lines := 0, 0
if err != nil {
log.Fatal(err)
}
defer file.Close()
reader := csv.NewReader(file)
for {
record, err := reader.Read()
if err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
q := q{question: record[0], answer: record[1]}
if q.ask() {
if verbose {
fmt.Println("Correct")
}
correct++
} else if verbose {
fmt.Println("Incorrect")
}
lines++
}
fmt.Printf("You had %d/%d correct answers!\n", correct, lines)
}
func main() {
// Setup flags.
p := flag.String("path", "problems.csv", "Specify the path to the quiz questions.")
v := flag.Bool("verbose", false, "A boolean value to check if you want the program to be verbose or not.")
flag.Parse()
// Invoke loop.
quizLoop(*p, *v)
}正如我在介绍中提到的,我对该语言相当陌生,在这个特定的项目中使用接口或go例程可能是有益的,但我看不出任何警告。
以下是我最感兴趣的评论:
发布于 2018-02-01 17:56:15
我注意到两件事:
file, err := os.Open(path)
correct, lines := 0, 0
if err != nil {
log.Fatal(err)
}
defer file.Close()我看不出有机会利用这里的围棋套路。这个程序本质上是连续的。我相信你以后会有个节选的。
发布于 2018-03-07 21:50:42
q结构有两个角色:
最好将这些职责分开:结构不应该有ask()函数。
与此相关的是,没有充分的理由在ask函数中重新创建扫描仪。
一个选项可以是创建一个新的ask(...)函数,该函数将扫描器、问题和答案作为参数。通过这种方法,q struct变得毫无意义。
要使q struct合法,您可以编写一个读取CSV并将q实例推送到通道的func qreader(file *os.File, qs chan q)。当主线程从通道读取并处理用户交互时,这个qreader可以在一个goroutine中运行。
程序忽略scanner.Scan()的返回值。为scanner.Err()保存不必要的检查可能是有用的。
养成怀疑地查看不返回值的语句(必须是变异状态)或其返回值被忽略的非空语句的习惯是很好的。
Go鼓励短名,但我认为q太短,对结构来说没有意义。至少,qa会更好地捕捉问题回答对的概念。我会叫它questionAnswer。
发布于 2018-02-02 09:25:11
如果您真的想使用goroutines和通道,可以在goroutine中读取csv文件:
questions := make(chan q)
go pushQuestions(questions) // type: func(chan<- questions)
// it closes the channel when all questions are red
for q := range questions {
q.ask()
...
}https://codereview.stackexchange.com/questions/186067
复制相似问题