FAQ
I was reading the "The way to Go" book where I found this example

#matrix/matrix.go
package matrix
type matrix struct {
a int
b int
}
func NewMatrix() *matrix {
return new(matrix)
}

#testmatrix.go
package main
import "./matrix"
import "fmt"
func main() {
m := matrix.NewMatrix()
fmt.Println(m) // This works
fmt.Printf("%d %d\n", m.a, m.b) // But cant do this
}

$ go run testmatrix.go
./testmatrix.go:10: m.a undefined (cannot refer to unexported field or
method a)
./testmatrix.go:10: m.b undefined (cannot refer to unexported field or
method b)

How can I access m.a and m.b since the definition of matrix itself cannot
be accessed ? Neither I can assign it to a alias of matrix which is
declared as "type M matrix". The "m" variable seems not useful in anyway.

Regards.

--

Search Discussions

  • Steve wang at Jan 3, 2013 at 1:32 pm
    You can always access a struct's exported fields and methods even though
    the struct itself is not exported.
    On Thursday, January 3, 2013 9:22:56 PM UTC+8, Prashant Shah wrote:

    I was reading the "The way to Go" book where I found this example

    #matrix/matrix.go
    package matrix
    type matrix struct {
    a int
    b int
    }
    func NewMatrix() *matrix {
    return new(matrix)
    }

    #testmatrix.go
    package main
    import "./matrix"
    import "fmt"
    func main() {
    m := matrix.NewMatrix()
    fmt.Println(m) // This works
    fmt.Printf("%d %d\n", m.a, m.b) // But cant do this
    }

    $ go run testmatrix.go
    ./testmatrix.go:10: m.a undefined (cannot refer to unexported field or
    method a)
    ./testmatrix.go:10: m.b undefined (cannot refer to unexported field or
    method b)

    How can I access m.a and m.b since the definition of matrix itself cannot
    be accessed ? Neither I can assign it to a alias of matrix which is
    declared as "type M matrix". The "m" variable seems not useful in anyway.

    Regards.
    --
  • Prashant Shah at Jan 3, 2013 at 4:27 pm
    Hi,
    On Thursday, January 3, 2013 7:02:41 PM UTC+5:30, steve wang wrote:

    You can always access a struct's exported fields and methods even though
    the struct itself is not exported.
    How do I do that, that is what I wanted to ask.

    Regards.

    --
  • Steve wang at Jan 3, 2013 at 5:45 pm

    On Friday, January 4, 2013 12:27:22 AM UTC+8, Prashant Shah wrote:
    Hi,
    On Thursday, January 3, 2013 7:02:41 PM UTC+5:30, steve wang wrote:

    You can always access a struct's exported fields and methods even though
    the struct itself is not exported.
    How do I do that, that is what I wanted to ask.

    Regards.
    As you have seen in the book, you can export a function which return an
    un-exported struct that has exported fields and/or methods.
    Here is another example:
    // tool.go
    package main
    import (
    "shape"
    "fmt"
    )
    func main() {
    rec := shape.NewRectangle(10, 20)
    fmt.Println(rec.Area())
    }
    // shape.go
    package shape
    type rectangle struct {
    width int
    length int
    }
    func (p *rectangle) Area() int {
    return p.width * p.length
    }
    // an exported function with a returned struct which is not exported yet
    func NewRectangle(width, length int) *rectangle {
    return &rectangle{width, length}
    }

    the hierarchy output by the "tree" command:
    ├── shape
    │ └── shape.go
    ├── tool
    │ └── tool.go

    --
  • Prashant Shah at Jan 3, 2013 at 5:58 pm
    Hi,
    On Thursday, January 3, 2013 11:15:41 PM UTC+5:30, steve wang wrote:

    As you have seen in the book, you can export a function which return an
    un-exported struct that has exported fields and/or methods.
    Here is another example:
    // tool.go
    package main
    import (
    "shape"
    "fmt"
    )
    func main() {
    rec := shape.NewRectangle(10, 20)
    fmt.Println(rec.Area())
    }
    // shape.go
    package shape
    type rectangle struct {
    width int
    length int
    }
    func (p *rectangle) Area() int {
    return p.width * p.length
    }
    // an exported function with a returned struct which is not exported yet
    func NewRectangle(width, length int) *rectangle {
    return &rectangle{width, length}
    }

    the hierarchy output by the "tree" command:
    ├── shape
    │ └── shape.go
    ├── tool
    │ └── tool.go
    rec.width (error)
    This makes sense. I can call methods on it, but I cant directly access the
    internal data - I have to use methods to do that.

    rec := shape.NewRectangle(10, 20)
    Also, if I am not wrong I cant declare it with "var rec..". I have to use
    the short hand format.

    Regards.

    --
  • Steve wang at Jan 3, 2013 at 6:16 pm

    On Friday, January 4, 2013 1:58:47 AM UTC+8, Prashant Shah wrote:
    Hi,
    On Thursday, January 3, 2013 11:15:41 PM UTC+5:30, steve wang wrote:

    As you have seen in the book, you can export a function which return an
    un-exported struct that has exported fields and/or methods.
    Here is another example:
    // tool.go
    package main
    import (
    "shape"
    "fmt"
    )
    func main() {
    rec := shape.NewRectangle(10, 20)
    fmt.Println(rec.Area())
    }
    // shape.go
    package shape
    type rectangle struct {
    width int
    length int
    }
    func (p *rectangle) Area() int {
    return p.width * p.length
    }
    // an exported function with a returned struct which is not exported yet
    func NewRectangle(width, length int) *rectangle {
    return &rectangle{width, length}
    }

    the hierarchy output by the "tree" command:
    ├── shape
    │ └── shape.go
    ├── tool
    │ └── tool.go
    rec.width (error)
    This makes sense. I can call methods on it, but I cant directly access the
    internal data - I have to use methods to do that.
    If you change the declaration of rectangle to:
    type rectangle struct {
    Width, Length int
    }
    then you can access these two exported fields outside the "shape" package.

    rec := shape.NewRectangle(10, 20)
    Also, if I am not wrong I cant declare it with "var rec..". I have to use
    the short hand format.
    You can't declare a variable of rectangle directly because the *type* is
    not exported. But you can get an *instance* of this type throgh the
    exported factory function, which is the only way you can get an instance of
    the rectange type.

    Regards.
    --
  • Prashant Shah at Jan 4, 2013 at 5:17 am
    Hi,
    On Thursday, January 3, 2013 11:41:05 PM UTC+5:30, steve wang wrote:


    rec.width (error)
    This makes sense. I can call methods on it, but I cant directly access
    the internal data - I have to use methods to do that.
    If you change the declaration of rectangle to:
    type rectangle struct {
    Width, Length int
    }
    then you can access these two exported fields outside the "shape" package.
    That works :)

    Regards.

    --
  • Chris dollin at Jan 3, 2013 at 2:18 pm

    On 3 January 2013 13:22, Prashant Shah wrote:
    I was reading the "The way to Go" book where I found this example

    #matrix/matrix.go
    I can't find that example on what might be the
    relevant website viz

    https://sites.google.com/site/thewaytogo2012/Downhome/Topic3

    Can you tell us what the book said the example was
    supposed to be about?

    [a struct with two ints in it doesn't seem very
    matrixy to me -- I'm expecting to see, say, a slice of
    numbers to hold the matrix elements. And methods to
    operate over the matrix without exposing the size
    fields.]

    Chris

    --
    Chris "allusive" Dollin

    --
  • Prashant Shah at Jan 3, 2013 at 4:18 pm
    Hi,
    On Thursday, January 3, 2013 7:39:56 PM UTC+5:30, chris dollin wrote:

    I can't find that example on what might be the
    relevant website viz

    https://sites.google.com/site/thewaytogo2012/Downhome/Topic3

    Can you tell us what the book said the example was
    supposed to be about?
    I cant find the example in the code samples. Uploading a screen-shot of the
    page.

    http://imgur.com/piQM7

    m := matrix.NewMatrix()

    IMHO, the above code should throw an error and not succeed.

    Regards.

    --
  • Miki Tebeka at Jan 3, 2013 at 4:14 pm

    On Thursday, January 3, 2013 5:22:56 AM UTC-8, Prashant Shah wrote:

    #matrix/matrix.go
    package matrix
    ...
    #testmatrix.go
    package main
    ...
    The test is in different package than the code, so it can't access
    unexported items.
    Changing testsmatrix.go to be in package matrix should do the trick.

    --
  • Prashant Shah at Jan 3, 2013 at 4:22 pm
    Hi,
    On Thursday, January 3, 2013 9:44:07 PM UTC+5:30, Miki Tebeka wrote:
    On Thursday, January 3, 2013 5:22:56 AM UTC-8, Prashant Shah wrote:

    #matrix/matrix.go
    package matrix
    ...
    #testmatrix.go
    package main
    ...
    The test is in different package than the code, so it can't access
    unexported items.
    Changing testsmatrix.go to be in package matrix should do the trick.
    I am aware of that part :)

    I wanted to clarify if its using a factory method to create a matrix object
    which itself in not exported, it should not allow to be created from
    another package at all even through functions that create a matrix object
    and return a pointer to matrix.

    Regards.

    --
  • Matt Kane's Brain at Jan 3, 2013 at 4:46 pm
    It's possible for an unexported type to have exported methods that conform
    to a particular public interface.
    On Thu, Jan 3, 2013 at 11:22 AM, Prashant Shah wrote:

    Hi,

    On Thursday, January 3, 2013 9:44:07 PM UTC+5:30, Miki Tebeka wrote:
    On Thursday, January 3, 2013 5:22:56 AM UTC-8, Prashant Shah wrote:

    #matrix/matrix.go
    package matrix
    ...
    #testmatrix.go
    package main
    ...
    The test is in different package than the code, so it can't access
    unexported items.
    Changing testsmatrix.go to be in package matrix should do the trick.
    I am aware of that part :)

    I wanted to clarify if its using a factory method to create a matrix
    object which itself in not exported, it should not allow to be created from
    another package at all even through functions that create a matrix object
    and return a pointer to matrix.

    Regards.

    --



    --
    matt kane's brain
    http://hydrogenproject.com

    --
  • Blakeamitch at Jan 3, 2013 at 4:54 pm
    It's not m the compiler is complaining about as not being exported, it's a
    and b.

    type matrix struct {
    A int
    B int
    }

    //...
    m := new(matrix)
    fmt.Println(m.A, m.B)
    On Thursday, January 3, 2013 5:22:56 AM UTC-8, Prashant Shah wrote:

    I was reading the "The way to Go" book where I found this example

    #matrix/matrix.go
    package matrix
    type matrix struct {
    a int
    b int
    }
    func NewMatrix() *matrix {
    return new(matrix)
    }

    #testmatrix.go
    package main
    import "./matrix"
    import "fmt"
    func main() {
    m := matrix.NewMatrix()
    fmt.Println(m) // This works
    fmt.Printf("%d %d\n", m.a, m.b) // But cant do this
    }

    $ go run testmatrix.go
    ./testmatrix.go:10: m.a undefined (cannot refer to unexported field or
    method a)
    ./testmatrix.go:10: m.b undefined (cannot refer to unexported field or
    method b)

    How can I access m.a and m.b since the definition of matrix itself cannot
    be accessed ? Neither I can assign it to a alias of matrix which is
    declared as "type M matrix". The "m" variable seems not useful in anyway.

    Regards.
    --
  • Nate Finch at Jan 3, 2013 at 7:27 pm
    Just a note, because no one has explicitly said this - types, fields, and
    methods that start with a lowercase letter are private to (not exported
    from) the package they're defined in. Names that start with an uppercase
    letter are pubic (exported from the package).

    In the case of the code you posted, matrix, a, and b are all unexported
    (private), which means they can't be accessed from the outside. Either
    this is a typo, or there's something missing (like exported functions on
    the type that are accessible). As written, the NewMatrix method is pretty
    useless, since it returns a struct with no externally visible fields or
    methods.

    If testmatrix were in the same package as matrix, it would be able to
    access those unexported fields.

    Are you sure you have the casing correct for the matrix struct?
    On Thursday, January 3, 2013 8:22:56 AM UTC-5, Prashant Shah wrote:

    I was reading the "The way to Go" book where I found this example

    #matrix/matrix.go
    package matrix
    type matrix struct {
    a int
    b int
    }
    func NewMatrix() *matrix {
    return new(matrix)
    }

    #testmatrix.go
    package main
    import "./matrix"
    import "fmt"
    func main() {
    m := matrix.NewMatrix()
    fmt.Println(m) // This works
    fmt.Printf("%d %d\n", m.a, m.b) // But cant do this
    }

    $ go run testmatrix.go
    ./testmatrix.go:10: m.a undefined (cannot refer to unexported field or
    method a)
    ./testmatrix.go:10: m.b undefined (cannot refer to unexported field or
    method b)

    How can I access m.a and m.b since the definition of matrix itself cannot
    be accessed ? Neither I can assign it to a alias of matrix which is
    declared as "type M matrix". The "m" variable seems not useful in anyway.

    Regards.
    --
  • Kyle Lemons at Jan 3, 2013 at 8:59 pm

    On Thu, Jan 3, 2013 at 11:27 AM, Nate Finch wrote:

    Just a note, because no one has explicitly said this - types, fields, and
    methods that start with a lowercase letter are private to (not exported
    from) the package they're defined in. Names that start with an uppercase
    letter are pubic (exported from the package).

    In the case of the code you posted, matrix, a, and b are all unexported
    (private), which means they can't be accessed from the outside.
    To be slightly more precise, you cannot spell any field, variable,
    constant, method, function, etc that is not exported (i.e. starts with a
    capital letter). The fact that matrix is unexported, for instance, does
    not prevent you from getting one as a return value. User-defined types
    which have a basic underlying type can be created by passing an untyped
    constant where one would be expected. You can even have variables in your
    code of another package's unexported type as long as you don't have to
    spell out the name of that type to get it.

    Either this is a typo, or there's something missing (like exported
    functions on the type that are accessible). As written, the NewMatrix
    method is pretty useless, since it returns a struct with no externally
    visible fields or methods.

    If testmatrix were in the same package as matrix, it would be able to
    access those unexported fields.

    Are you sure you have the casing correct for the matrix struct?

    On Thursday, January 3, 2013 8:22:56 AM UTC-5, Prashant Shah wrote:

    I was reading the "The way to Go" book where I found this example

    #matrix/matrix.go
    package matrix
    type matrix struct {
    a int
    b int
    }
    func NewMatrix() *matrix {
    return new(matrix)
    }

    #testmatrix.go
    package main
    import "./matrix"
    import "fmt"
    func main() {
    m := matrix.NewMatrix()
    fmt.Println(m) // This works
    fmt.Printf("%d %d\n", m.a, m.b) // But cant do this
    }

    $ go run testmatrix.go
    ./testmatrix.go:10: m.a undefined (cannot refer to unexported field or
    method a)
    ./testmatrix.go:10: m.b undefined (cannot refer to unexported field or
    method b)

    How can I access m.a and m.b since the definition of matrix itself cannot
    be accessed ? Neither I can assign it to a alias of matrix which is
    declared as "type M matrix". The "m" variable seems not useful in anyway.

    Regards.

    --
    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJan 3, '13 at 1:23p
activeJan 4, '13 at 5:17a
posts15
users8
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase