import "fmt"
func main(){
fmt.Print("Hello World")
}go run app.go-
Main function is the entry point for whole GO application
-
Print is a method that comes from the fmt package
-
Strings are only allowed in double quotes or backticks only
-
Every Go file needs a package imported that will be same as the file name
-
Idea for packages is to organize code
-
package can be made up of multiple files
- Go can by itself get the type of values being stored in the variable, but we can also declare a type so that we can say what value can be stored there and with that we can remove any extra type conversion
var investmentAmount float64 = 1000- explicit type can be added after the variable name
- variables can be declared via “var” keyword
- and also with special assignment operator “:=” so with that we can remove the “var” keyword
- this assignment operator is useful when we dont have to change the type of variable that is assigned by GO
- because with “:=” we can not declare the type of variable
expectedReturn float64 := 5.5above is invalid
expectedReturn := 5.5above is valid
- we can declare multiple variables at the same time with same type
var investmentAmount, years float64 = 1000, 10- if we dont declare the type of variable on that line then we can also declare multiple variables with different types
var investmentAmount, years = 1000, "10"- Getting values from users through cli is pretty similar to how it is done in C language
- we can use the Scan() method of the fmt package to do that.
fmt.Scan(&investmentAmount)- here the investmentAmount is already declared and it has a value in it so to override that we are using the “&” symbol, which is a pointer to the actual variable and here will override the value from user input
- If user dont give any value to the variable, it will be initialized with the default value of the type, for float it will be 0.0
- We can declare a variable without initializing any value to that variable, but for that, we will need to explicitly declare the type of the variable, which required as GO Lang is a statically typed language
- This will be declared using the var keyword and then the variable name and then the type of variable
var years float64
var expectedReturn float64const inflationRate = 2.5
var investmentAmount float64 = 1000
var years float64
expectedReturn := 5.5- there are different option to add to the output string that can format it
- here we have
%vand\nthat helped to add the variable value and also with\neverything after it will be on next line - There are many of these “verbs that we can add to format, check the official docs
- We can use
%.0fto round the floating numbers - the number before f refers to the number we wanna show after the .
- so if we say
%.2fthat will print 2 number after .
fmt.Printf("Future Value : %v\nFuture Value (Adjusted for Inflation): %v", futureValue, futureRealValue)- using the method
Sprintf()we can store any formatted string into a variable and then use that variable instead of whole string
formattedFV := fmt.Sprintf("Future Value : %.0f\n", futureValue)
formattedFRV := fmt.Sprintf("Future Value (Adjusted for Inflation): %0.f\n", futureRealValue)- after that we can use the Print() method to print these strings which will just print the string without any formatting
fmt.Print(formattedFV, formattedFRV)- We can use backticks ```` instead of double quotes to create multiline formatted string, this way
fmt.Printf(`Future Value : %v Future Value (Adjusted for Inflation): %v`, futureValue, futureRealValue)- all the user defined Functions are defined below the
mainfunction - a function in Go can be defined using
funckeyword - We can add parameters to the function, when adding parameters we have to define the type of the parameter
func outputText(text1 string, text2 string){
fmt.Print()
}- if the parameters are of same type then we can define the parameter and have the type only once, then we have to add the parameter name and at the end add the type of the parameter
func outputText(text1, text2 string) {
fmt.Print()
}- After that we can use it like any other function in any language
outputText("Investment Amount: ")
fmt.Scan(&investmentAmount)
func outputText(text1 string) {
fmt.Print(text1)
}- in Go lang, we can return multiple values from a single function
- In Go, variables are block scoped, which means any variables defined inside the function or block are scoped to that function and we can use them outside the function
- We can define the variables outside the main function or any other function to have them as global scope and then we can use them inside any function in the file.
- We can only define const and var declaration as global declaration, we cannot do this to any other declaration
- That means
:=syntax cannot be used in the global scope
const inflationRate = 2.5
func main() {
var investmentAmount float64 = 1000
var years float64
var expectedReturn = 5.5
}- when returning any value, we have to define the return type of the function
- If we are returning 2 values we have to wrap it into rounded parenthesis, and then define the type of specific return to its type
- with this we can define specific types to any return value
func demo ()(float64, int){}
func calculateFutureValue(investmentAmount, expectedReturn, years float64) (float64, float64) {
fv := (investmentAmount) * math.Pow(1+expectedReturn/100, float64(years))
rfv := fv / math.Pow(1+inflationRate/100, years)
return fv, rfv
}- when we want to store the return values in the variable, we can have 2 variable by comma separated variable names
futureValue, futureRealValue := calculateFutureValue(investmentAmount, expectedReturn, years)- when you declare the type of variables on function, there you can also add the variables name, and that way you dont have to declare those return variables
- also then you dont have to add those variable names after the return statement, Go will understand which variables to return
func calculateFutureValue(investmentAmount, expectedReturn, years float64) (fv float64, rfv float64) {
fv = (investmentAmount) * math.Pow(1+expectedReturn/100, float64(years))
rfv = fv / math.Pow(1+inflationRate/100, years)
return
}- starting new project with command
go mod init example.com/bank- Booleans for checks
wantsCheckBalance := choice == 1- if condition is similar but only round parenthesis is not used, directly the condition is used
if choice == 1 || choice == 2 {
}- All the conditional
&&and||are also the same - to check the condition or compare we can use the double equals operator
== else ifis also the same as other language
if choice == 1 {
fmt.Println("Your Balance is", accountBalance)
} else if choice == 2 {
}- Increment operator works the same
accountBalance += depositAmount
//which equals to accountBalance = accountBalance + depositAmount- In Go lang there is only
for loop, other than this there are no loops - So, same as conditionals, loops does not have round brackets to wrap around the condition
for i := 0; i < 200; i++ {}- they are directly declared with the
:=syntax for the variable declaration
- if we define a for loop without any condition then that loop can work as an infinite loop
for {
fmt.Println("===============")
fmt.Println("What do you want to do?")
}- one way to get out of the infinite loop in this case would be to use
returnstatement but with that whole program will be stopped and anything added after that will not be executed
- So to get out of the loops we can use the
breakstatement, which will stop the loop and start executing next line of the loop - We can use
continuestatement to break out of any particular condition and get back to the main loops, this helps when working with conditions inside a loop, so that way we can stop any particular condition and start the loops again continuestatement will stop the current iteration of the loop and start again that loop
- It is same as the other languages, nothing specific to GO in this
switch choice {
case 1:
fmt.Println("Your Balance is", accountBalance)
case 2:
fmt.Print("Your Deposit: ")
case 3:
fmt.Print("Withdrawal Amount:")
default:
fmt.Print("Goodbye!")
}- the
os packageprovides a function calledWriteFilethat takes in the name of the package, the data to be stored in the file and file mode, which will be the file modifying permissions.
func writeBalanceFiles(balance float64) {
balanceText := fmt.Sprint(balance)
os.WriteFile("balance.txt", []byte(balanceText), 0644)
}- sometimes when we are getting 2 return values from a function, we can then use a special variable name
_that means we want get the value but we dont want to use it.
data, _ := os.ReadFile("balance.txt")- here the data will come with a
bytetype, so to handle that, we can only convert that data into a string - we need the data string in float number, so for that we can use the
strconvpackage, that gives us different methods to handle string operations - we can use
ParseFloatmethod, which will convert the string into floating number, with that we will need to provide thestring valueandbitSizewhich will be 32 or 64
func readFile() float64 {
data, _ := os.ReadFile("balance.txt")
balanceText := string(data)
balance, _ := strconv.ParseFloat(balanceText, 64)
return balance
}- byte values cannot be directly converted into any type other then string and string value directly cannot be converted into any other type, that will require the use of
strconvpackage
- In GO, there is a special type as
errorthat can be used to give out custom errors which comes from the built inerrors package - In GO, we can use
nilto check the null value - almost all packages provide an error as return value with a main value, we use the error to to check if there is
nilvalue - So, if the error is not nil that means there is an error and in that case we can give out some error response
if err != nil {
return 1000, errors.New("failed to find balance file")
} var accountBalance, err = readFile()
if err != nil {
fmt.Println("ERROR")
fmt.Println(err)
fmt.Println("===============")
}- We can split code in multiple files, then split those files in multiple packages
- then we can use those packages in out projects
- It seems similar to making components, splitting code into multiple files to handle code in better way, that way we can create our own packages too
- we can just create a new
.gofile - every go file must be part of a package
- whenever we declare a file in the same package as other file then we can just directly use the functions in any file of the same package
- e.g., we create a file with a function, to call that function in a different file we can have both the file in same package, and then directly call the function
- Imports are not passed directly through packages
- so we have to import other packages that are being used in the function of the new go file
- If you create multiple files into a package, then you can use that package into different projects, that way you can have a package that has code that you use again and again then that code goes into a package and that package can be used in another project for the same purpose
- To create a custom package we will have to create a new folder for that package
- the folder name should be the same as the package
- the file name can be different, does not need to be same as the package
package fileops
import (
"errors"
"fmt"
"os"
"strconv"
)
func writeFloatToFile(value float64, fileName string) {
valueText := fmt.Sprint(value)
os.WriteFile(fileName, []byte(valueText), 0644)
}- Here I have a package named fileops for which i have folder names fileops which contains a file
- that file can be named anything, on top of the file i declared the package name which my file is part of
- to use this custom package, you have to import it, the process is same as other inbuilt packages
- but in this case you have to point out to the path same as the
go.modfile
package main
import (
"fmt"
"example.com/bank/fileops"
)- here the
example.com/bankcomes from thego.modfile which was created when creating the project
- if you are using some function from a different package, and you have created that package, you will have to export those functions
- To export something from a package, that as to be defined in a way so that the name is starting from an uppercase
func WriteFloatToFile(value float64, fileName string) {}
func GetFLoatFromFile(fileName string) (float64, error) {}- this works as same as
exportkeyword in JavaScript, where we define a function or variable with export keyword and explicitly, define that, that variable or functions needs to be exported and can be used in other files - So the naming of the function or variable can define if something is exported or not
package main
import (
"fmt"
"example.com/bank/fileops"
)
fileops.WriteFloatToFile(accountBalance, accountBalanceFile)

