Reader.readstring Won't Read Type String in Golang
Learning Go By Example: Part 1
I strive to be a lifelong learner and enjoy learning new things. I prefer to learn skills by seeing and working with examples. I particularly like learning new programming languages and frameworks and have been wanting to pick upward Go for quite a while. There are plenty of groovy resources to learn Get including the wonderful https://tour.golang.org/ that offers a hands on bout of the Go language. There are also several proficient books on Get including:
- The Go Programming Language
- Head Start Go
- Go in Action
- Get Programming in Go
- Introducing Go
These are wonderful resources. I was eager to start coding and used these resources equally I dove into the Golang pool.
Why Acquire Go?
I know quite a few programming languages why should I larn some other ane, especially Get? Start of all, Go has quite a full-blooded. It was created by software engineering science legends Brian W. Kerninghan, Rob Pike, and Robert Griesemer. A number of important software projects including Docker and Kubernetes, have been written in Become. Here is a post that makes a compelling case for Go. A meliorate question might be, why not acquire Go?
The First Example: Finding Hashtags
My daughter recently started taking her first programming form and her schoolhouse selected Python to teach students the fundamentals. I am very fond of Python and thought it was a proficient choice. I eagerly volunteered to be my daughter'south unofficial TA.
I've known Python for a long time, merely can think only i time in which I used it professionally. Nevertheless, I "think" in Python. When I write pseudocode, I usually write it in a Python-esque manner. One of my daughter'south first assignments was to write a hashtag finder. The plan had to read in tweets and print out all the included hashtags. It was a fairly straightforward exercise:
def main():
while Truthful:
tweet = input("Enter tweet: ")
if tweet.lower() == "quit":
print("Goodbye!")
pausewords = tweet.split up(" ")
has_hastags = False
for word in words:
if give-and-take[0] == '#':
print("Hashtag: ", word)
has_hastags = True if not
has_hastags:
print("No hastags") if __name__ == "__main__":
chief()
The code to a higher place is very readable except for the somewhat esoteric manner in which chief code blocks are defined in Python. Rewriting this example in Become turned out to be a fairly simple practice:
package mainimport "bufio"
import "fmt"
import "bone"
import "strings"
func main() {
var reader = bufio.NewReader(os.Stdin)
for {
fmt.Impress("Enter tweet: ")
var tweet, _ = reader.ReadString('\northward')
if strings.EqualFold(tweet, "quit\n") {
fmt.Println("Cheerio!")
intermission
}
var words = strings.Separate(tweet, " ")
var hasHashTags = false;
for _, word := range words {
if word[0] == '#' {
fmt.Println("Hashtag: ", word)
hasHashTags = truthful
}
}
if !hasHashTags {
fmt.Println("No hashtags")
}
}
}
This code is also very readable fifty-fifty for a Go newbie.
package principalimport "bufio"
import "fmt"
import "os"
import "strings"
The snippet to a higher place defines the main code block (a bit simpler than Python) and the required imported packages (i.e. libraries) for the plan.
func chief() {
var reader = bufio.NewReader(bone.Stdin)
This code snippet defines the master
function and creates a reader
variable that holds a reference to a buffered reader from standard input. The keyword var
is used to define variables. We'll apply the reader
variable to read a string from the keyboard. This is similar to something we would run across in other languages like C or Coffee. It'southward non needed in Python because standard input is implied in Python'southward input
function. Notice that the NewReader
role is from the bufio
package which we included in an import
statement above.
for {
fmt.Print("Enter tweet: ")
var tweet, _ = reader.ReadString('\n') if strings.EqualFold(tweet, "quit\due north") {
fmt.Println("Good day!")
suspension
}
...
This code snippet defines an infinite loop which is equivalent to the Python while True:
loop. Nosotros and so prompt the user to enter their tweet. The phone call to the ReadString
method is interesting because information technology returns two values. All Go functions (and methods) are able to render multiple values which can be very useful. The value is the string from standard input and stored in the tweet
variable. The 2nd value is the resulting error code. In this case, we employ the _
grapheme to ignore information technology. We could've also written var tweet, errorCode := reader.ReadString('\n'),
merely since we won't be using the error code, we can avoid a compiler error by ignoring it (the Get compiler doesn't allow unused variables). The '\n'
defines the terminating delimiter of the cord. In other words, it returns the string upward to, and including the new line delimiter.
The EqualFold
function performs a case insensitive comparing of the tweet and the value "quit\n". Notice that nosotros had to include the trailing newline character in the comparison.
Functions versus methods
I desire to make a quick note nearly the difference betwixt functions and methods. In the snippet above, EqualFold
is considered to be a function because is referenced directly from the strings
packet. ReadString
is considered a method considering information technology's referenced from the object reference contained in the reader
variable.
var words = strings.Split(tweet, " ")
var hasHashTags = false;
for _, word := range words {
if give-and-take[0] == '#' {
fmt.Println("Hashtag: ", give-and-take)
hasHashTags = true
}
} if !hasHashTags {
fmt.Println("No hashtags")
}
In the code snippet in a higher place, nosotros use the Split up
function to pause up the tweet into separate words that are stored in the assortment contained in the words
variable. We and so ascertain a strange looking for
loop. We can define an index in the starting time part of a for
loop. Since nosotros won't be needing one, we use the _
character to ignore it. The for
loop iterates through all the words in words
array. The give-and-take
variable contains the word of the current iteration. This variable is merely scoped within the for
loop and cannot be used outside the loop. If the starting time byte of the word is a #
grapheme, that word is a hashtag and nosotros print information technology and prepare the hasHashTags
variable to truthful. Afterward the for
loop, if hasHashTags
is still false, and then we print that we did not find any hashtags.
Refactoring the code
There are few things that we tin practise to better this example and make information technology a ameliorate Go program:
bundle mainimport (
"bufio"
"fmt"
"bone"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
for {
fmt.Impress("Enter tweet: ")
tweet, _ := reader.ReadString('\north')
if strings.EqualFold(strings.TrimSpace(tweet),"quit") {
fmt.Print("Exiting...")
suspension
}
hashtags := findHashTags(tweet)
for _, hashtag := range hashtags {
fmt.Printf("Hashtag: %due south\north", hashtag)
}
if len(hashtags) == 0 {
fmt.Impress("No hashtags")
}
}
}
func findHashTags(tweet string) []string {
var hashtags[] string
words := strings.Split(tweet, " ")
for _, word := range words {
if word[0] == '#' {
hashtags = append(hashtags, word)
}
}
return hashtags
}
It'south better style to group all the imports into a single parenthesized, "factored" import statement:
import (
"bufio"
"fmt"
"os"
"strings"
)
That makes it a little improve to read.
reader := bufio.NewReader(os.Stdin)
Nosotros can use the :=
operator to ascertain and assign variables. This is a shortcut for var reader = bufio.NewReader(bone.Stdin)
.
if strings.EqualFold(strings.TrimSpace(tweet),"quit") {
fmt.Print("Exiting...")
break
}
In this code snippet, nosotros use the TrimSpace
function to remove all whitespace from the tweet
variable so nosotros can compare to a more simple "quit" value.
hashtags := findHashTags(tweet)for _, hashtag := range hashtags {
fmt.Printf("Hashtag: %s\n", hashtag)
}
if len(hashtags) == 0 {
fmt.Print("No hashtags")
}
In the lawmaking snippet above, we broke out the hashtag code into its own separate part, findHashTags
which returns an array with the associated hashtags. The for
loop iterates through this array and prints out the hashtags. If the array is empty (its length is zip), nosotros print out a message that no hashtags were plant.
The findHashTags
function is fairly straightforward:
func findHashTags(tweet string) []string {
var hashtags[] cord
words := strings.Split(tweet, " ") for _, discussion := range words {
if give-and-take[0] == '#' {
hashtags = append(hashtags, word)
}
}
return hashtags
}
The first line defines findHashTags
as a office that takes in a string parameter and returns a string array. The function uses array slices to build the return value contained in the hashtags
variable. We tin can view slices equally references to arrays. That effectively allows u.s. to treat them as dynamic arrays to which we tin append values: hashtags = append(hashtags, discussion)
.
Type inference
Go is a statically typed linguistic communication just it allows for inferred typing. For example, in this snippet:
words := strings.Split(tweet, " ")
the variable words
is not explicitly typed. The type is inferred from the function strings.Divide
. We could've also written: var words[] string = strings.Split)tweet, " ")
.
Summary
This was a adequately simple case, only I promise that it helps start your journey to learning and condign literate in Become. We'll continue to mail service more intricate examples to learn additional Get features and idioms. Hither is my second Become post.
Source: https://medium.com/swlh/learning-go-by-example-part-1-97bf80bbac59
0 Response to "Reader.readstring Won't Read Type String in Golang"
Publicar un comentario