<p>So, I decided to try Go, starting with the basics of course.<br/>
And the simplest way I found to read a line from stdin and print it back is this:</p>
<pre><code>package main
import ("fmt"
"bufio"
"os"
"strings")
func main() {
var name string
reader := bufio.NewReader(os.Stdin)
fmt.Println("What is your name?")
name, _ = reader.ReadString('\n')
name = strings.TrimSpace(name)
fmt.Printf("Hi, %s!\n", name)
}
</code></pre>
<p>And it took half an hour just to puzzle these together. I still can't understand why fmt.Scanln doesn't work (its documentation says it reads until a newline, so why doesn't it do that?) and have no idea what's going on above in lines 11 and 13, and if I haven't already known some C, I wouldn't be able to figure out why writing <em>"\n"</em> in reader.ReadString() didn't work in line 13. But the fact that I need 4 imports just to read and write a string seems to be a huge overkill to me.<br/>
Does Go get any easier later or does everything need so much work?</p>
<hr/>**评论:**<br/><br/>nohoudini: <pre><p>Go is simple but repetitive. Go has taught me how the Single Responsability Principle & dependency injection is used well. I was in the same boat and thought it's a very overkill but after some time you realize that the components are well split and make sense.</p></pre>nwss00: <pre><p>If you want a language where you don't have to care much about implementation details then check out Ruby.</p>
<p>Ruby solves things in 1 line and whenever you ask why, you're always given a strange look and reply, "It just works. Forget about the nitty-gritty and move on."</p></pre>dimitrios_gopher: <pre><p>In ruby, it is really easy for a bad programmer to write complicated code and hide many flaws or bugs.</p>
<p>In Go, it is really easy for a bad programmer to write simple code and their errors will be glaringly obvious, which can be easily spotted and fixed.</p>
<p>Anyways, still recovering from the horrors of my Rails days. Magic sucks. Screw magic. </p></pre>mgutz: <pre><p>Or Perl! But yeah, the hardest part of learning Go is unlearning what you've learned from other languages. Once you do, Go becomes a rewarding experience. </p>
<p>As for imports, you rarely have to manage those. Editors with Go support do that automatically. It's no different than Java, C# in that sense.</p></pre>oefig: <pre><blockquote>
<p>But the fact that I need 4 imports just to read and write a string seems to be a huge overkill to me.</p>
</blockquote>
<p>Four imports to do it the way you want to do it. Really, you just need <code>fmt</code>, and <code>strings</code> if you want to use <code>strings.TrimSpace</code>.</p>
<pre><code>package main
import (
"fmt"
"strings"
)
func main() {
var name string
fmt.Println("What is your name?")
fmt.Scanln(&name)
fmt.Printf("Hi, %s!\n", strings.TrimSpace(name))
}
</code></pre>
<blockquote>
<p>I still can't understand why fmt.Scanln doesn't work (its documentation says it reads until a newline, so why doesn't it do that?)</p>
</blockquote>
<p>If you posted your code we could probably tell you why it doesn't. As demonstrated above, <code>fmt.Scanln</code> does exactly that.</p></pre>OctaviaPinfold: <pre><p>Scanln stops scanning at the first space.</p></pre>PM_ME_MY_REAL_MOM: <pre><p>This is what the <a href="https://golang.org/pkg/fmt/#Scan" rel="nofollow">docs</a> say about <code>fmt.Scan</code> and <code>fmt.Scanln</code>:</p>
<blockquote>
<p>Scan scans text read from standard input, storing successive space-separated values into successive arguments. Newlines count as space. It returns the number of items successfully scanned. If that is less than the number of arguments, err will report why.</p>
</blockquote>
<hr/>
<blockquote>
<p>Scanln is similar to Scan, but stops scanning at a newline and after the final item there must be a newline or EOF.</p>
</blockquote>
<hr/>
<p>So as documented, <code>fmt.Scanln</code> is reading from stdin, separating the input by spaces, and storing the results in the arguments provided. Since you only provided one argument, only the first word was returned. I think <code>fmt.Scanln</code> is not the most suitable for reading a single line from stdin, if you don't need it tokenized.</p>
<p>You're looking for a single string of arbitrary length that ends with a newline, and you want to trim the spaces on the ends of that string. I'd say your original implementation is ideal.</p>
<p>Yes, Go is a verbose language. I wouldn't say that makes it <em>difficult</em>; so your question "Does it get easier?" is, I don't know. I come from the Ruby world and find the explicitness of Go refreshing, but many don't, and Go has other similar shortcomings that will turn those developers away.</p>
<p>Best of luck to you!</p></pre>OctaviaPinfold: <pre><p>Oh, so it also creates multiple results separated by spaces. That wording was a bit confusing, I read the documentation again and again but kept assuming Scanln can read multiple lines like Scan reads multiple "words".</p></pre>metamatic: <pre><p>It's scanning multiple values from a line, rather than scanning lines.</p>
<p>Similarly with sql.Scan, it's scanning multiple values from a row rather than scanning rows. So at least there's some consistency.</p></pre>geodel: <pre><p>You really need to move to NodeJS. Put a few dozen plugin and code will write itself.</p></pre>kardianos: <pre><p>Go isn't optimized for one-liners. Writing a single line of code doesn't amount to a single unit of work.</p>
<p>Go has good readability. Let me read your program back you you:</p>
<ol>
<li>Create a buffered reader from stdin.</li>
<li>Print to std out a question.</li>
<li>Read text from the buffer, stop reading at the newline (enter key).</li>
<li>Remove leading and trailing spaces from the answer.</li>
<li>Print the answer out to you.</li>
</ol>
<p>I'm not sure what you're expecting. If you'd like to use the fmt package, you could do the following:</p>
<pre><code>package main
import (
"fmt"
"log"
"strings"
)
func main() {
fmt.Println("my question?")
var ans string
_, err := fmt.Scanln(&ans)
if err != nil {
log.Fatal("scan err", err)
}
fmt.Printf("my ans: %q\n", strings.TrimSpace(ans))
}
</code></pre>
<p>Make sure you read the docs; don't assume something is intended to work how you think it should work, verify your assumptions with the docs.</p></pre>OctaviaPinfold: <pre><p>With this I get </p>
<pre><code>2017/10/29 20:58:08 scan errexpected newline
exit status 1
</code></pre>
<p>Edit: It works only if there's no space in the input.</p></pre>wavy_lines: <pre><blockquote>
<p>Does Go get any easier later or does everything need so much work?</p>
</blockquote>
<p>I don't think it gets "easier" in any sense except that you get used to it.</p>
<p>Go is verbose. It's probably less verbose than C or Java, but it's still verbose if you're coming from a python background.</p>
<p>Python is optimized for short scripts. Go is not optimized for that. Go discourages creating many layers of abstraction. </p></pre>shovelpost: <pre><p>Scanning from the standard input, while it sounds trivial, it can be surprisingly tricky because it has a lot of corner cases. It's not much better in other languages either. Don't let it discourage you.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传