Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .tours/1-go-syntax-and-conventions.tour
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
{
"file": "async/main.go",
"line": 68,
"description": "## for loops\r\n🔵 ***Language & Syntax*** \r\n\r\nGo has one type of loop: the \"for\" loop. The good news is that this can be used the same as \"for\", \"foreach\", and \"while\" in C#. \r\n\r\n**Indexed for loop** \r\n```go\r\n for i := 0; i < len(ids); i++ {\r\n // use the indexer here.\r\n }\r\n```\r\nSimilar to a \"for\" loop in C#, the \"for\" loop in go can be used as a loop with an indexer. In this loop, the built-in \"len\" function gives us the length of the \"ids\" slice. \r\n\r\n**Iteration (foreach)** \r\n```go\r\n for index, value := range ids {\r\n a := ids[index]\r\n b := value\r\n // a & b have the same value.\r\n }\r\n```\r\nThe \"for\" loop can be used with a range similar to a \"foreach\" in C#. The loop will iterate one time for each item in the range. Unlike \"foreach\" in C#, using \"range\" in Go returns two values: the index and the value. This gives us the option of using the indexer or the actual item value. Often we want to use just one of these inside the loop, so we use the blank identifier (\"_\") for the one we do not need.\r\n\r\nNote: if we do not need to capture the value or the indexer (we just want to iterate a certain number of times), we can leave out the variable assignments.\r\n\r\n```go\r\n for range ids {\r\n // the body will run based on the number of items in the range\r\n }\r\n```\r\n\r\n**while** \r\nIn C#, we can set up a \"while\" loop that will continue until some condition is false. Generally the condition is impacted by the contents of the loop. Go uses \"for\" for this.\r\n\r\n```go\r\n while command != \"stop\" {\r\n // do something\r\n command = getNextCommand()\r\n }\r\n```\r\n\r\n**Endless Loops (while(true))** \r\nSometimes in C#, we want to use a \"while(true)\" as an endless loop that is terminated with a break statement inside the loop body. This can be done using \"for\" with no condition in Go. \r\n\r\n```go\r\n for {\r\n // endless loop that runs until \"break\" is used.\r\n }\r\n```\r\n\r\n**break & continue** \r\n\"break\" and \"continue\" can be used on \"for\" loops in Go. They behave just the same as in C#. \"break\" stops the loop; \"continue\" moves to the next iteration of the loop."
"description": "## for loops\r\n🔵 ***Language & Syntax*** \r\n\r\nGo has one type of loop: the \"for\" loop. The good news is that this can be used the same as \"for\", \"foreach\", and \"while\" in C#. \r\n\r\n**Indexed for loop** \r\n```go\r\n for i := 0; i < len(ids); i++ {\r\n // use the indexer here.\r\n }\r\n```\r\nSimilar to a \"for\" loop in C#, the \"for\" loop in go can be used as a loop with an indexer. In this loop, the built-in \"len\" function gives us the length of the \"ids\" slice. \r\n\r\n**Iteration (foreach)** \r\n```go\r\n for index, value := range ids {\r\n a := ids[index]\r\n b := value\r\n // a & b have the same value.\r\n }\r\n```\r\nThe \"for\" loop can be used with a range similar to a \"foreach\" in C#. The loop will iterate one time for each item in the range. Unlike \"foreach\" in C#, using \"range\" in Go returns two values: the index and the value. This gives us the option of using the indexer or the actual item value. Often we want to use just one of these inside the loop, so we use the blank identifier (\"_\") for the one we do not need.\r\n\r\nNote: if we do not need to capture the value or the indexer (we just want to iterate a certain number of times), we can leave out the variable assignments.\r\n\r\n```go\r\n for range ids {\r\n // the body will run based on the number of items in the range\r\n }\r\n```\r\n\r\n**while** \r\nIn C#, we can set up a \"while\" loop that will continue until some condition is false. Generally the condition is impacted by the contents of the loop. Go uses \"for\" for this.\r\n\r\n```go\r\n for command != \"stop\" {\r\n // do something\r\n command = getNextCommand()\r\n }\r\n```\r\n\r\n**Endless Loops (while(true))** \r\nSometimes in C#, we want to use a \"while(true)\" as an endless loop that is terminated with a break statement inside the loop body. This can be done using \"for\" with no condition in Go. \r\n\r\n```go\r\n for {\r\n // endless loop that runs until \"break\" is used.\r\n }\r\n```\r\n\r\n**break & continue** \r\n\"break\" and \"continue\" can be used on \"for\" loops in Go. They behave just the same as in C#. \"break\" stops the loop; \"continue\" moves to the next iteration of the loop."
},
{
"file": "async/main.go",
Expand Down Expand Up @@ -170,7 +170,7 @@
{
"file": "async/main.go",
"line": 41,
"description": "## Error handling\r\n🔶 ***Program Structure*** \r\n\r\nAs mentioned above, a common pattern is for a function to return a data value and and error. A common pattern for checking errors is shown above. If a function returns an error, we check to see if the error is nil. If it is not nil (meaning, there was an error), we handle the error by adding our own message and passing it along.\r\n\r\nThis error check is in the \"getPerson\" function. If the result from the service cannot be parsed into the \"person\" struct (using the \"Decode\" function), an error will be returned.\r\n\r\n**fmt.Errorf** \r\nIf there is an error, we use the \"Errorf\" function to add our own message to the error object and pass it along as a return value for the \"getPerson\" function.\r\n\r\n**Error conventions** \r\nThe convention for handling errors is to prepend the error with your own message. In this example, we add \"error parsing person:\" to the error that is returned from the JSON decoder. Since this message will potentially be prepended by whatever method gets this error, certain conventions are followed: \r\n\r\n* The error message should start with a lower case letter. \r\n* The error message should not contain periods or other terminating characters.\r\n* The error message should not contain new line characters. \r\n\r\nThese conventions keep the error message as a single string that is read similar to a call stack: the first part of the string is the outermost message, then each message works its way inward until the final part of the string shows the initial error. Note that these conventions are enforced by the Go linter that is part of the Go extension for Visual Studio Code. \r\n\r\n**Exceptions** \r\nYou probably notice that error handling involving strings is handled as part of the normal code flow -- meaning, it's up to the developer to decide what to do with an error. This is different from exceptions in C# where the flow control passes from the developer to the system, the call stack is unwound, and exceptions move up until they reach an appropriate handler. \r\n\r\nGo does have an equivalent of an exception which is a **panic**. This is reserved for true unexpected / illegal states, such as trying to read beyond the end of an array or writing to a closed channel. A panic cannot be handled and (similar to an unhandled exception) will cause the application to exit. \r\n\r\nThe general philosophy of error handling in Go is that we deal with expected situations (such as an error status coming back from a web server) using **error**. ",
"description": "## Error handling\r\n🔶 ***Program Structure*** \r\n\r\nAs mentioned above, a common pattern for a function is to return a data value and error. A common pattern for checking errors is shown above. If a function returns an error, we check to see if the error is nil. If it is not nil (meaning, there was an error), we handle the error by adding our own message and passing it along.\r\n\r\nThis error check is in the \"getPerson\" function. If the result from the service cannot be parsed into the \"person\" struct (using the \"Decode\" function), an error will be returned.\r\n\r\n**fmt.Errorf** \r\nIf there is an error, we use the \"Errorf\" function to add our own message to the error object and pass it along as a return value for the \"getPerson\" function.\r\n\r\n**Error conventions** \r\nThe convention for handling errors is to prepend the error with your own message. In this example, we add \"error parsing person:\" to the error that is returned from the JSON decoder. Since this message will potentially be prepended by whatever method gets this error, certain conventions are followed: \r\n\r\n* The error message should start with a lower case letter. \r\n* The error message should not contain periods or other terminating characters.\r\n* The error message should not contain new line characters. \r\n\r\nThese conventions keep the error message as a single string that is read similar to a call stack: the first part of the string is the outermost message, then each message works its way inward until the final part of the string shows the initial error. Note that these conventions are enforced by the Go linter that is part of the Go extension for Visual Studio Code. \r\n\r\n**Exceptions** \r\nYou probably notice that error handling involving strings is handled as part of the normal code flow -- meaning, it's up to the developer to decide what to do with an error. This is different from exceptions in C# where the flow control passes from the developer to the system, the call stack is unwound, and exceptions move up until they reach an appropriate handler. \r\n\r\nGo does have an equivalent of an exception which is a **panic**. This is reserved for true unexpected / illegal states, such as trying to read beyond the end of an array or writing to a closed channel. A panic cannot be handled and (similar to an unhandled exception) will cause the application to exit. \r\n\r\nThe general philosophy of error handling in Go is that we deal with expected situations (such as an error status coming back from a web server) using **error**. ",
"selection": {
"start": {
"line": 39,
Expand Down