FAQ
I am wondering why this isn't allowed?

------------------------------------------
package main

import (
     "io"
     "os"
     "time"
)

type File interface {
     io.ReadCloser
     Stat() (os.FileInfo, error)
}

type FileInfo struct {
     name string
     size int64
     mode os.FileMode
     modTime time.Time
     isDir bool
     sys interface{}
}

func (f FileInfo) Name() string {
     return f.name
}
func (f FileInfo) Size() int64 {
     return f.size
}

func (f FileInfo) Mode() os.FileMode {
     return f.mode
}

func (f FileInfo) ModTime() time.Time {
     return f.modTime
}

func (f FileInfo) IsDir() bool {
     return f.isDir
}

func (f FileInfo) Sys() interface{} {
     return f.sys
}

type VirtualFile struct {
     io.ReadCloser
     FileInfo FileInfo
}

func (vf VirtualFile) Stat() (FileInfo, error) {
     return vf.FileInfo, nil
}

var (
     _ os.FileInfo = FileInfo{} //Even though our FileInfo is os.FileInfo.
     _ File = VirtualFile{}
)
------------------------------------------

It gives me the following error:


------------------------------------------

prog.go:57: cannot use VirtualFile literal (type VirtualFile) as type File in assignment:
  VirtualFile does not implement File (wrong type for Stat method)
   have Stat() (FileInfo, error)
   want Stat() (os.FileInfo, error)

------------------------------------------

Play: http://play.golang.org/p/OsLVzKcTCX

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Egon at Mar 1, 2015 at 9:24 am

    On Sunday, 1 March 2015 09:17:05 UTC+2, omei...@gmail.com wrote:
    I am wondering why this isn't allowed?
    Basically, they are different types.

    http://golang.org/ref/spec#Properties_of_types_and_values

    + Egon

    ------------------------------------------
    package main

    import (
    "io"
    "os"
    "time"
    )

    type File interface {
    io.ReadCloser
    Stat() (os.FileInfo, error)
    }

    type FileInfo struct {
    name string
    size int64
    mode os.FileMode
    modTime time.Time
    isDir bool
    sys interface{}
    }

    func (f FileInfo) Name() string {
    return f.name
    }
    func (f FileInfo) Size() int64 {
    return f.size
    }

    func (f FileInfo) Mode() os.FileMode {
    return f.mode
    }

    func (f FileInfo) ModTime() time.Time {
    return f.modTime
    }

    func (f FileInfo) IsDir() bool {
    return f.isDir
    }

    func (f FileInfo) Sys() interface{} {
    return f.sys
    }

    type VirtualFile struct {
    io.ReadCloser
    FileInfo FileInfo
    }

    func (vf VirtualFile) Stat() (FileInfo, error) {
    return vf.FileInfo, nil
    }

    var (
    _ os.FileInfo = FileInfo{} //Even though our FileInfo is os.FileInfo.
    _ File = VirtualFile{}
    )
    ------------------------------------------

    It gives me the following error:


    ------------------------------------------

    prog.go:57: cannot use VirtualFile literal (type VirtualFile) as type File in assignment:
    VirtualFile does not implement File (wrong type for Stat method)
    have Stat() (FileInfo, error)
    want Stat() (os.FileInfo, error)

    ------------------------------------------

    Play: http://play.golang.org/p/OsLVzKcTCX
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jan Mercl at Mar 1, 2015 at 11:29 am

    On Sun, Mar 1, 2015 at 8:16 AM wrote:

    I am wondering why this isn't allowed?
    Because Go is a statically typed language and because the only implicit
    conversion Go sports is from non interface types to interface types and
    from untyped constants to appropriate types.

    However, it's not needed in this case to be alloweda at all, this version
    works just fine: http://play.golang.org/p/Y2mFFR_HJA

    The only change is to follow the method signature as declared.

    -j

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Omeid Me at Mar 1, 2015 at 12:35 pm

    On Sunday, March 1, 2015 at 10:30:10 PM UTC+11, Jan Mercl wrote:

    On Sun, Mar 1, 2015 at 8:16 AM <omei...@gmail.com <javascript:>> wrote:

    I am wondering why this isn't allowed?
    Because Go is a statically typed language and because the only implicit
    conversion Go sports is from non interface types to interface types and
    from untyped constants to appropriate types.

    However, it's not needed in this case to be alloweda at all, this version
    works just fine: http://play.golang.org/p/Y2mFFR_HJA

    The only change is to follow the method signature as declared.

    -j
    Perhaps my example wasn't very clear.

    Your example wouldn't allow the users of VirtualFile to get a FileInfo
    (which may have more methods than os.FileInfo). That is exactly the issue
    that I run with.

    I ended up with having an extra wrap to go around it,

    like so

    `
    type StrictFile struct {
         VirtualFile
    }

    func (sf StrictFile) Stat() (os.FileInfo, error) {
         return sf.VirtualFile.Stat()
    }
    `

    http://play.golang.org/p/B76xsMZrKC

    I am guessing this is the best option to have interoperability in
    situations like this?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jan Mercl at Mar 1, 2015 at 12:48 pm

    On Sun, Mar 1, 2015 at 1:35 PM wrote:
    Your example wouldn't allow the users of VirtualFile to get a FileInfo
    (which may have more methods than os.FileInfo).
    User can access it just fine: http://play.golang.org/p/44dYkUU9b8

    The same way is used, for example, to access system specific
    implementations of stdlib's os.FileInfo.Sys()

    -j

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Omeid Me at Mar 1, 2015 at 1:15 pm

    On Sunday, March 1, 2015 at 11:49:43 PM UTC+11, Jan Mercl wrote:
    On Sun, Mar 1, 2015 at 1:35 PM <omei...@gmail.com <javascript:>> wrote:
    Your example wouldn't allow the users of VirtualFile to get a FileInfo
    (which may have more methods than os.FileInfo).
    User can access it just fine: http://play.golang.org/p/44dYkUU9b8

    The same way is used, for example, to access system specific
    implementations of stdlib's os.FileInfo.Sys()

    -j

    Sorry, I think I wasn't clear enough, the users can use the FileInfo as
    (os.FileInfo) not FileInfo, the type, if I was to return os.FileInfo from
    the VirtualFile.Stat.

    I want to have a common interface between os.File and a Virtualfile.

    Here is an example: http://play.golang.org/p/VuhVdeXjcz

    Can this be improved?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jan Mercl at Mar 1, 2015 at 2:01 pm
    User within the package can use any type defined in that package. Importers
    of this package can use FileInfo because it's exported. User aquaring your
    type wrapped in File or os.Info can use it through its methods or can
    access the specific type instance via a type switch or through type
    assertion as demonstrated earlier.

    Yes, be removing the superfluous StrictFile type, the only purpose it
    serves can be achieved without it, as shown earlier.

    The problem you're solving is legitimate, the proposed solution is not. 1)
    The signature of a method implementing an interface must match semantically
    exactly. 2) Accessing concrete type instances through interface is easy and
    idiomatic in Go, just use that. 3) Adding special variants of methods to
    the method set of a well known interface is not making the new/resulting
    method set "common", it makes it different and incompatible with the
    original interface.

    -j (phone)

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMar 1, '15 at 7:16a
activeMar 1, '15 at 2:01p
posts7
users3
websitegolang.org

3 users in discussion

Omeid Me: 3 posts Jan Mercl: 3 posts Egon: 1 post

People

Translate

site design / logo © 2021 Grokbase