Why when we reference struct using (*structObj) does Go seem to return a new copy of structObj rather than return the same address of original
No, "assignment" always creates a copy in Go, including assignment to function and method arguments. The statement obj := *p copies the value of *p to obj.
If you change the statement p.color = "purple" to (*p).color = "purple" you will get the same output, because dereferencing p itself does not create a copy.