DEV Community

Cover image for Go lang: Datatypes, Variables, Constants, Pointers and User input
Chiranjeevi Tirunagari
Chiranjeevi Tirunagari

Posted on • Updated on • Originally published at vchiranjeeviak.hashnode.dev

Go lang: Datatypes, Variables, Constants, Pointers and User input

In my previous article, I discussed about installation, initialization, writing hello world program, running a program and creating executable files for different operating systems.

Link to my previous article on Go lang

In this article, we are going to discuss about types, variables, constants, pointer and user input.

Data Types

Let's first talk about data types present in Go.

go data types.png

If we talk in general terms, we have bool (true or false), int (positive and negative integers), float (numbers with decimal points), string (characters, sentences), complex (numbers having imaginary values, don't bother about these unless you are dealing with Math).

What else do we need? You can go through all sizes of them, if you are dealing with some OS stuff.

Variables

Since, we saw the datatypes, now it makes sense to start with variables.

A variable is an user-defined (defined by us) storage container whose value can be changed at any time. We can give any name to any variable (hey, but giving a meaningful name is a good practice).

Syntax of declaring a variable (just declaring it, not giving any value):

var <variable name> <datatype>

We can declare a variable like this and assign a value to it later or we can assign value while declaring it which is called as initializing a variable.

Syntax of initializing a variable:

var <variable name> <datatype> = <value>

Let me introduce my self using an example here:

package main

import "fmt"

func main(){
    var myName string // just declaring a string variable
    var myAge int = 20 // Initializing an int variable with value 20
    myName = "Chiranjeevi" // Now assigning value to the above declared variable
    fmt.Println("My name is ", myName) // We can print variables along with a string like this
    fmt.Print("My age:")
    fmt.Print(myAge) // We can also print it individually
    // Println and Print has nothing to do with variables, 
    //Println prints in new line and Print prints in same line.
}
Enter fullscreen mode Exit fullscreen mode

Above is the actual way to deal with variables. But we can do it in other ways too.

We don't need to specify the type of the variable while initializing.

package main

import "fmt"

func main(){
    var marksInOS int = 98 // explicitly mentioning datatype
    var marksInDBMS = 99 // not mentioning datatype explicitly
    // They both are of same type
    // You can check by printing their datatypes
    fmt.Printf("Datatype of marksInOS is %T", marksInOS)
    fmt.Printf("Datatype of marksInDBMS is %T", marksInDBMS)
}
Enter fullscreen mode Exit fullscreen mode

Let's make it even simpler, we don't even need to write var keyword.
I know your inner feeling.

you: "Why don't you just come to the point?"
me: "That's how learning programming works"

On a side note, everything has it's own use case. So, it's good to know all ways.

Now let's come to the point.

To not use var keyword, we need to use a special operator called 'walrus' operator. It looks like ':=' .

Mathematicians after seeing this: ' Hey pal, I know you'.

Yes, it's used to assign values in mathematics and that's what it is used for in Go lang too.

An important thing to remember is that walrus operator can't be used in a global scope (outside functions). It can be used in a function scope.

Final example on variables:

package main

func main(){
    var email string = "vchiranjeeviak.tirunagari@gmail.com"
    var name = "chiranjeevi"
    age := 20 // walrus : let's chill
}
Enter fullscreen mode Exit fullscreen mode

Constants

A constant is just like a variable which is an user-defined storage container but whose value can't be changed after initialization.

Let's say we are writing a program to calculate area of a circle when it's radius is given. We need pie here which is 3.14 or 22/7. Pie value doesn't need to be changed and it's same for any circle.

In these scenarios, we store these values using constants.

Syntax for initializing a constant:

const <constant name> <datatype> = <value>

Just like in case of variables, we don't need to specify datatype.

const <constant name> = <value>

An example:

package main

import "fmt"

func main(){
    const pie = 3.14
    radius := 5
    area := pie * radius * radius
    fmt.Println("Area of circle with radius 5 is ", area)
}
Enter fullscreen mode Exit fullscreen mode

Pointers

Let's not over-complicate this simple topic.

What is a pointer?

A pointer is a variable, which stores the address of the other variables.

Can it store the address of any variable? No.

Just like how variables have a datatype, pointers also have a datatype. A pointer can be of type bool, int, float etc.

A pointer of a type can store the address of variables of same type. It can't store the addresses of the variables of other datatypes.

Syntax of declaring a pointer:

var <pointer name> *<datatype>

'*' indicates that we are declaring a pointer.

Example:

func main(){
    var ptr *int 
    // Here ptr is the name that we have given to the pointer.
    // Our ptr pointer is of type int
}
Enter fullscreen mode Exit fullscreen mode

How do we get the address of a variable?

We can get the address of the variable using ampersand (&) operator before the name of the variable.

var <pointer name> *<datatype> = &<other variable name>

Let's say we initialized a variable called num of type int whose value is 10. Now let's store the address of the num in our ptr pointer:

import "fmt"

func(){
    var num int = 10
    var ptr *int = &num
    fmt.Println("The address stored in ptr is ", ptr)
    // To see the address stored in ptr which is the address of num.
}
Enter fullscreen mode Exit fullscreen mode

Let's assume a scenario.

You are writing code in a function called fun1. You have access to another function called fun2 which you can call in the current function fun1. You don't know the body of fun2 but what you know is that it returns an address of a variable. Now you are calling this fun2 in fun1. As you know that fun2 return an address, you will have to store what it returns in a pointer. Let's say you are storing it in a pointer called ptr. How do you see value present at the address stored in ptr?

We can see the value present in an address stored in a pointer using asterisk (*) operator.

In above scenario, *ptr would give us the value present at the address stored in ptr. Not just getting the value, we can even change the value at that address using this operator. I hope you get some sense how pointers can be useful.

import "fmt"

func(){
    var num int = 10
    fmt.Println("Value of num is ", num)
    var ptr *int = &num // Assigning address of num to ptr
    fmt.Println("Address stored in ptr is ", ptr)
    fmt.Println("Value at address stored in ptr is ", *ptr)
    // We can even change the value present at that address
    *ptr = *ptr * 2 // This would change the value present at address stored in ptr
    fmt.Println("After changing....")
    fmt.Println("Value at address stored in ptr is ", *ptr)
    fmt.Println("Value of num is ", num)
    // The value of num changes as the address stored in ptr is the address of num
    // which we changed
}
Enter fullscreen mode Exit fullscreen mode

Why do we even need these addresses? might be a question.

Let's assume another small scenario. You are getting input from user. Where do you store it? In memory. Every memory location has address. So, to store something, we need to deal with addresses.

We actually don't do these in languages like Java, JavaScript, Python etc. It's because, we need to have JRE to run Java programs, Python interpreter for python and NodeJS to run JavaScript which take care of these memory things under the hood so that we don't need to work hard. But, Go doesn't expect any runtime environment to run. So, er need to take care of them by ourselves.

There are many other situations where we need address. But for now this is enough.

User input

Taking user input is the necessary thing in any programming language. So, let's do that.

We print something on screen by using functions present in 'fmt' package. Similarly, 'fmt' also has functions to take user input too.

The function we use to take input is 'Sscanln'. It holds the prompt for user to give input. It considers everything as input until the user hits enter. Basically, whole line as input. We need to give the address of the variable in which we want to store the data. (see, addresses. So, pointers.)

Syntax:

fmt.Scanln(&<variable name>)

Let's finish this article by completing the above area of circle program with user input.

package main

import "fmt"

func main(){
    const pie = 3.14 // Constant
    fmt.Println("Enter the radius of cirlce: ") // Printing to screen
    var radius int // Variable
    fmt.Sscanln(&radius) // Address and taking input
    var area = pie * radius * radius // Calculation
    fmt.Println("The area of circle is ", area) // Printing to screen
}
Enter fullscreen mode Exit fullscreen mode

The End

That's it for this one. Next article will be on type conversions, comma-error syntax, time package, memory management etc.

My socials:

Twitter
LinkedIn
Showwcase

Discussion (0)