If I run the following code everything compiles and runs fine:
package main
import "fmt"
type Point struct {
x, y int
}
func (p *Point) init() bool {
p.x = 5
p.y = 10
return true
}
func main() {
point := Point{}
point.init()
fmt.Println(point)
}
But when I move the Point struct to a package in the $GOPATH directory then I get the following error: point.init undefined (cannot refer to unexported field or method class.(*Point)."".init)
Can anyone explain to me why this happens?
Once I put the Point struct in a package called class the code looks as follows (the error is on the 8th line where I call the init method):
package main
import "fmt"
import "class"
func main() {
point := class.Point{}
point.init()
fmt.Println(point)
}
Rename init() to Init() should work!
Basically, all the things(function, method, struct, variable) that not start with an Unicode upper case letter will just visible inside their package!
You need to read more from the language spec here:
http://golang.org/ref/spec#Exported_identifiers
Relevant bit:
An identifier may be exported to permit access to it from another package. An identifier is exported if both:
the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu"); and
the identifier is declared in the package block or it is a field name or method name.
All other identifiers are not exported.
Only functions/methods that have the first letter of their name capitalized are exported
http://golang.org/doc/effective_go.html#commentary
Every exported (capitalized) name in a program...
When I changed init to Init everything worked.
Related
Is it possible to call an extension function from another package without importing it?
Given an extension function:
package ext
fun Int.plusOne() = this + 1
Is there any way to call this function without importing the function first?
I can call non-extension functions without an import (ignore that the function does not need to be imported, just note that the syntax is valid):
val el: List<Int> = kotlin.emptyList()
I can instantiate classes without an import:
val str = java.lang.String("yo.")
But I have not yet found the equivalent for extensions (I know some examples are silly):
val i = 42
// All those are not valid syntax...
i.ext.plusOne()
ext.plusOne(i)
i.(ext.plusOne)()
i.(ext.plusOne())
ext.i.plusOne()
val pO = ext.plusOne
i.pO()
Bonus: Same question, but for extension properties.
Edit: To add to the list of invalid examples, even at places where the extension receiver is implicit, FQDNs are not allowed:
// Good:
import ext.plusOne
val four = with(3) { plusOne() }
// Unresolved reference:
val four = with(3) { ext.plusOne() }
No, according to the spec. A call can only be these forms:
A fully-qualified call without receiver: package.foo();
A call with an explicit receiver: a.foo();
An infix function call: a foo b;
An overloaded operator call: a + b;
A call without an explicit receiver: foo().
Notice that the "fully-qualified call" form, which is the only form that allows the use of package names, explicitly says "without receiver". However, your plusOne requires an Int as a receiver. In fact, by definition, all extensions functions/properties require a receiver by definition.
I also tried looking at callable references, in hopes of making a callable reference to plusOne using a fully qualified name, and then calling that callable reference. However, it turns out the syntax for those is even stricter.
Therefore, this cannot be done without modifying the ext package in some way, like adding a "wrapper" function.
After all, there is really no need for such a feature. Importing is not that hard - the IDE does it all for you these days. If you need to import two things with the same name, use an import alias:
import package1.extFunc as pack1ExtFunc
import package2.extFunc as pack2ExtFunc
The question is in the comment. I want to refer to the outer function append, and not the one that's defined in the StringBuilder, how do I do this?
fun append(c: Char) {
println("TEST")
}
fun sbTest() = with(StringBuilder()) {
for(c in 'A'..'Z') {
append(c) // how do I refer to the append function declared above?
}
toString()
}
I know I can introduce a function reference variable, like this:
val f = ::append
and call f instead of append, but is there another way?
The problem is that anything called within with shadows the outer functions, because this is introduced. The same problem appears if you have a class and a top-level function with a function with the same signature.
The obvious option would just be re-naming it. Also, the function you have there isn't really descriptive compared to what it actually does. But if you for some reason can't rename, there are still other options.
Top-level methods can be referenced by package in Kotlin, for an instance like com.some.package.method. It can also be imported as such, which is the most common way to do it. There are very few methods that are called as com.some.package.method().
Kotlin, like Python, allows as in imports. Which means, you can do this:
package com.example;
// This is the important line; it declares the import with a custom name.
import com.example.append as appendChar; // Just an example name; this could be anything ***except append***. If it's append, it defeats the purpose
fun append(c: Char) {
println("TEST")
}
fun sbTest() = with(StringBuilder()) {
for(c in 'A'..'Z') {
appendChar(c)
}
toString()
}
Alternatively, as I mentioned, you can add the package:
for(c in 'A'..'Z') {
com.example.append(c)
}
val f = ::append is of course an option too, either way, it is still easier to rename the function than create imports with as or constants, assuming you have access to the function (and that it doesn't belong to a dependency).
If your file is outside a package, which I do not recommend you do, you can just declare the import as:
import append as appendChar
You could also use an extension function instead of with(), such as .let{...}.
This will send StringBuilder as an argument to the extension function as it (You can rename it to whatever you want btw):
fun sbTest() = StringBuilder().let{ it ->
for(c in 'A'..'Z') {
// using string builder
it.append(c)
// using your function
append(c)
}
it.toString()
}
The .let{...} function returns your last statement, aka the String from toString(), so your original function would still return it properly. Other functions can return this instead, such as .also{...}
I tend to use extension functions rather than with() as they're more flexible.
See this post to master extension functions: https://medium.com/#elye.project/mastering-kotlin-standard-functions-run-with-let-also-and-apply-9cd334b0ef84
EDIT: Got also{} and let{} mixed up. I switched them
Think like this :
package first
type person struct {
Name string
}
var Per = person{
Name: "Jack",
}
and in main package
package main
import "first"
import "fmt"
func main(){
o := first.Per
fmt.Println(o)
}
the above works, as we can see that the variable in first package was visible outside but it's type was not, but it gives no error? And how it can be useful outside package?
it is fine:
Exported identifiers:
An identifier may be exported to permit access to it from another
package. An identifier is exported if both:
the first character of the identifier's name is a Unicode upper case
letter (Unicode class "Lu"); and
the identifier is declared in the
package block or it is a field name or method name. All other
identifiers are not exported.
ref: https://golang.org/ref/spec
and even you can use Getters:
Go doesn't provide automatic support for getters and setters. There's
nothing wrong with providing getters and setters yourself, and it's
often appropriate to do so, but it's neither idiomatic nor necessary
to put Get into the getter's name. If you have a field called owner
(lower case, unexported), the getter method should be called Owner
(upper case, exported), not GetOwner. The use of upper-case names for
export provides the hook to discriminate the field from the method. A
setter function, if needed, will likely be called SetOwner. Both names
read well in practice:
owner := obj.Owner()
if owner != user {
obj.SetOwner(user)
}
ref: https://golang.org/doc/effective_go.html
so if you do not want to export Name make it lower case, like this working sample codes and use Getter/Setter :
package first
type person struct {
name string
}
var Per = person{
name: "Jack",
}
func (p *person) SetName(name string) {
p.name = name
}
func (p *person) Name() string {
return p.name
}
main.go (with commented output):
package main
import "first"
import "fmt"
func main() {
person := first.Per
fmt.Println(person.Name()) //Jack
person.SetName("Alex")
fmt.Println(person.Name()) //Alex
}
another use cases:
Singleton pattern
Essentially, it's a singleton pattern. The package exports a single instance of person but because the type is private you can't create another instance out of it.
Better implementation would be to export a function that returns a singleton instance of a private type. On first invocation it will create the instance in a thread-safe manner.
var (
p *person
once sync.Once
)
type person struct {
Name string
}
func Per() *person {
once.Do(func() {
p = &person{
Name: "Jack",
}
})
return p
}
sync.Once allows you to execute a piece of code only once even if multiple goroutines are trying to execute it.
In Golang the Scanner interface takes a single dest argument, which is any number of interface{}s:
// Scan copies the columns in the current row into the values pointed at by dest.
func (rs *Rows) Scan(dest ...interface{}) error
Is there an alternative function that can return a slice of interfaces as its result? Say I wanted to put the dest arguments in a function, so I didn't have to write them out every time.
func scanArgs() []interface{} {
}
func main() {
db.QueryRow("SELECT * FROM users").Scan(scanArgs()...)
}
I've tried this but I'm running into issues with the method signature; I can set a []interface as the return value, but I can't easily create one inside the function. Is there a better way to do this?
You can easily allocate inside the function with syntax like the following;
package main
import "fmt"
func main() {
objs := &[]interface{}{}
objs2 := make([]interface{}, 10)
objs3 := []interface{}{}
fmt.Println(len(*objs))
fmt.Println(len(objs2))
fmt.Println(len(objs3))
}
Since everything implements the empty interface you can add any type to those collections with append. The init syntax is a bit clunky and probably what's throwing you... The reason it looks like that is because I'm declaring the type interface{} there when typically you'd have the name of an actual interface like []io.Writer{}. Instead you need those extract curlys.
I have a struct and I would like it to be initialised with some sensible default values.
Typically, the thing to do here is to use a constructor but since go isn't really OOP in the traditional sense these aren't true objects and it has no constructors.
I have noticed the init method but that is at the package level. Is there something else similar that can be used at the struct level?
If not what is the accepted best practice for this type of thing in Go?
There are some equivalents of constructors for when the zero values can't make sensible default values or for when some parameter is necessary for the struct initialization.
Supposing you have a struct like this :
type Thing struct {
Name string
Num int
}
then, if the zero values aren't fitting, you would typically construct an instance with a NewThing function returning a pointer :
func NewThing(someParameter string) *Thing {
p := new(Thing)
p.Name = someParameter
p.Num = 33 // <- a very sensible default value
return p
}
When your struct is simple enough, you can use this condensed construct :
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33}
}
If you don't want to return a pointer, then a practice is to call the function makeThing instead of NewThing :
func makeThing(name string) Thing {
return Thing{name, 33}
}
Reference : Allocation with new in Effective Go.
There are actually two accepted best practices:
Make the zero value of your struct a sensible default. (While this looks strange to most people coming from "traditional" oop it often works and is really convenient).
Provide a function func New() YourTyp or if you have several such types in your package functions func NewYourType1() YourType1 and so on.
Document if a zero value of your type is usable or not (in which case it has to be set up by one of the New... functions. (For the "traditionalist" oops: Someone who does not read the documentation won't be able to use your types properly, even if he cannot create objects in undefined states.)
Go has objects. Objects can have constructors (although not automatic constructors). And finally, Go is an OOP language (data types have methods attached, but admittedly there are endless definitions of what OOP is.)
Nevertheless, the accepted best practice is to write zero or more constructors for your types.
As #dystroy posted his answer before I finished this answer, let me just add an alternative version of his example constructor, which I would probably write instead as:
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33} // <- 33: a very sensible default value
}
The reason I want to show you this version is that pretty often "inline" literals can be used instead of a "constructor" call.
a := NewThing("foo")
b := &Thing{"foo", 33}
Now *a == *b.
There are no default constructors in Go, but you can declare methods for any type. You could make it a habit to declare a method called "Init". Not sure if how this relates to best practices, but it helps keep names short without loosing clarity.
package main
import "fmt"
type Thing struct {
Name string
Num int
}
func (t *Thing) Init(name string, num int) {
t.Name = name
t.Num = num
}
func main() {
t := new(Thing)
t.Init("Hello", 5)
fmt.Printf("%s: %d\n", t.Name, t.Num)
}
The result is:
Hello: 5
I like the explanation from this blog post:
The function New is a Go convention for packages that create a core type or different types for use by the application developer. Look at how New is defined and implemented in log.go, bufio.go and cypto.go:
log.go
// New creates a new Logger. The out variable sets the
// destination to which log data will be written.
// The prefix appears at the beginning of each generated log line.
// The flag argument defines the logging properties.
func New(out io.Writer, prefix string, flag int) * Logger {
return &Logger{out: out, prefix: prefix, flag: flag}
}
bufio.go
// NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) * Reader {
return NewReaderSize(rd, defaultBufSize)
}
crypto.go
// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
if h > 0 && h < maxHash {
f := hashes[h]
if f != nil {
return f()
}
}
panic("crypto: requested hash function is unavailable")
}
Since each package acts as a namespace, every package can have their own version of New. In bufio.go multiple types can be created, so there is no standalone New function. Here you will find functions like NewReader and NewWriter.
In Go, a constructor can be implemented using a function that returns a pointer to a modified structure.
type Colors struct {
R byte
G byte
B byte
}
// Constructor
func NewColors (r, g, b byte) *Colors {
return &Color{R:r, G:g, B:b}
}
For weak dependencies and better abstraction, the constructor does not return a pointer to a structure, but an interface that this structure implements.
type Painter interface {
paintMethod1() byte
paintMethod2(byte) byte
}
type Colors struct {
R byte
G byte
B byte
}
// Constructor return intreface
func NewColors(r, g, b byte) Painter {
return &Color{R: r, G: g, B: b}
}
func (c *Colors) paintMethod1() byte {
return c.R
}
func (c *Colors) paintMethod2(b byte) byte {
return c.B = b
}
another way is;
package person
type Person struct {
Name string
Old int
}
func New(name string, old int) *Person {
// set only specific field value with field key
return &Person{
Name: name,
}
}
If you want to force the factory function usage, name your struct (your class) with the first character in lowercase. Then, it won't be possible to instantiate directly the struct, the factory method will be required.
This visibility based on first character lower/upper case work also for struct field and for the function/method. If you don't want to allow external access, use lower case.
Golang is not OOP language in its official documents.
All fields of Golang struct has a determined value(not like c/c++), so constructor function is not so necessary as cpp.
If you need assign some fields some special values, use factory functions.
Golang's community suggest New.. pattern names.
I am new to go. I have a pattern taken from other languages, that have constructors. And will work in go.
Create an init method.
Make the init method an (object) once routine. It only runs the first time it is called (per object).
func (d *my_struct) Init (){
//once
if !d.is_inited {
d.is_inited = true
d.value1 = 7
d.value2 = 6
}
}
Call init at the top of every method of this class.
This pattern is also useful, when you need late initialisation (constructor is too early).
Advantages: it hides all the complexity in the class, clients don't need to do anything.
Disadvantages: you must remember to call Init at the top of every method of the class.