confused with the interface's private method error message

312 views
Skip to first unread message

chai2010

unread,
Sep 18, 2014, 3:50:38 AM9/18/14
to golang-nuts
This is the play code:

type TB int
func (t TB) Error(args ...interface{})                 {}
...
func (t TB) Skipped() bool                             { return false }
func (t TB) private() {}
var tb testing.TB = new(TB)

Error message:

prog.go:28: cannot use new(TB) (type *TB) as type testing.TB in assignment:
*TB does not implement testing.TB (missing testing.private method)
have private()
want testing.private()
[process exited with non-zero status]

But I think the `TB` implement testing.TB.

Thie `testing.TB` with `.private()` is not a really private interface.

I we need a really private interface, we can define the inteface like this:

type privateType int

type TB interface {
private(privateType)
}

The `privateType` is a really private type, so the outside user can't define
a `private(privateType)` method for the private `testing.TB` interface.

Thanks.


--

Jan Mercl

unread,
Sep 18, 2014, 3:58:37 AM9/18/14
to chai2010, golang-nuts
On Thu, Sep 18, 2014 at 9:49 AM, chai2010 <chais...@gmail.com> wrote:
> But I think the `TB` implement testing.TB.

Interfaces having unexported methods cannot be implemented outside the
declaring package. In this case, testing.TB can be implemented only by
types declared in package testing.

-j

Jesse McNelis

unread,
Sep 18, 2014, 3:59:48 AM9/18/14
to chai2010, golang-nuts
On Thu, Sep 18, 2014 at 5:49 PM, chai2010 <chais...@gmail.com> wrote:
> prog.go:28: cannot use new(TB) (type *TB) as type testing.TB in assignment:
> *TB does not implement testing.TB (missing testing.private method)
> have private()
> want testing.private()
> [process exited with non-zero status]
>
> But I think the `TB` implement testing.TB.

It can't because the method required to implement the interface is
testing.private() not private().
That is, it needs to be a method called private() on a type defined in
the testing package.

Jan Mercl

unread,
Sep 18, 2014, 4:20:02 AM9/18/14
to Islan Dberry, golang-nuts
On Thu, Sep 18, 2014 at 10:10 AM, Islan Dberry <island...@gmail.com> wrote:
> Not true. See http://play.golang.org/p/4VSdjDf9si

Not true. See http://play.golang.org/p/LCFMs_Scbe and click "Run".

-j

Dan Kortschak

unread,
Sep 18, 2014, 8:48:05 AM9/18/14
to Jan Mercl, Islan Dberry, golang-nuts
Is private ever called within testing? It doesn't seem so, so there is
no real restriction on implementing the other parts. It's willfully
ignoring the DO NOT ENTER sign, but that's what people do.

roger peppe

unread,
Sep 18, 2014, 9:50:00 AM9/18/14
to Jan Mercl, Islan Dberry, golang-nuts
Jan, your code just means that external packages can't call the private
method, not that the implementation isn't implemented (if private was
called inside the testing package, it would work fine).

I don't really see why TB contains the private method tbh - it isn't used
by any of the exported testing functions or methods.

Probably not worth implementing though - just define your own.

Ian Lance Taylor

unread,
Sep 18, 2014, 11:15:30 AM9/18/14
to Dan Kortschak, Jan Mercl, Islan Dberry, golang-nuts
On Thu, Sep 18, 2014 at 5:47 AM, Dan Kortschak
<dan.ko...@adelaide.edu.au> wrote:
> Is private ever called within testing? It doesn't seem so, so there is
> no real restriction on implementing the other parts. It's willfully
> ignoring the DO NOT ENTER sign, but that's what people do.

See the comment in the source code.

// A private method to prevent users implementing the
// interface and so future additions to it will not
// violate Go 1 compatibility.
private()

Ian

roger peppe

unread,
Sep 18, 2014, 1:38:07 PM9/18/14
to Ian Lance Taylor, Dan Kortschak, Jan Mercl, Islan Dberry, golang-nuts
It's perhaps interesting that even though we now know that this
doesn't prevent users implementing the interface, it does
actually succeed in its original aim, because anyone that
implements the interface must at least embed that
interface, so must gain the benefit of any new exported methods
there. (They probably won't do the right thing of course,
but at least the programs will compile)

Dan Kortschak

unread,
Sep 18, 2014, 4:51:03 PM9/18/14
to Ian Lance Taylor, Jan Mercl, Islan Dberry, golang-nuts
Yes, aware of that. It is not called though as far as I can see.

Ian Lance Taylor

unread,
Sep 18, 2014, 5:27:34 PM9/18/14
to Dan Kortschak, Jan Mercl, Islan Dberry, golang-nuts
On Thu, Sep 18, 2014 at 1:50 PM, Dan Kortschak
<dan.ko...@adelaide.edu.au> wrote:
> Yes, aware of that. It is not called though as far as I can see.

It's not called. Merely by existing it ensures that no other code can
implement the testing.TB interface. That is the goal. There is no
reason to actually call it.

(It's true that other code can implement the interface using
inheritance, but that's OK because it can't cause that code to break.)

Ian

chai2010

unread,
Sep 18, 2014, 7:33:04 PM9/18/14
to Ian Lance Taylor, Dan Kortschak, Jan Mercl, Islan Dberry, golang-nuts
2014-09-19 5:26 GMT+08:00 Ian Lance Taylor <ia...@golang.org>:
On Thu, Sep 18, 2014 at 1:50 PM, Dan Kortschak
<dan.ko...@adelaide.edu.au> wrote:
> Yes, aware of that. It is not called though as far as I can see.

It's not called.  Merely by existing it ensures that no other code can
implement the testing.TB interface.  That is the goal.  There is no
reason to actually call it.

(It's true that other code can implement the interface using
inheritance, but that's OK because it can't cause that code to break.)
Does the spec have docs for interface's private method ? 

Ian

> On 19/09/2014, at 12:44 AM, "Ian Lance Taylor" <ia...@golang.org> wrote:
>
>> On Thu, Sep 18, 2014 at 5:47 AM, Dan Kortschak
>> <dan.ko...@adelaide.edu.au> wrote:
>>> Is private ever called within testing? It doesn't seem so, so there is
>>> no real restriction on implementing the other parts. It's willfully
>>> ignoring the DO NOT ENTER sign, but that's what people do.
>>
>> See the comment in the source code.
>>
>>    // A private method to prevent users implementing the
>>    // interface and so future additions to it will not
>>    // violate Go 1 compatibility.
>>    private()
>>
>> Ian

--
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...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Dan Kortschak

unread,
Sep 18, 2014, 7:52:27 PM9/18/14
to Ian Lance Taylor, Jan Mercl, Islan Dberry, golang-nuts
On Thu, 2014-09-18 at 14:26 -0700, Ian Lance Taylor wrote:
> It's not called. Merely by existing it ensures that no other code can
> implement the testing.TB interface. That is the goal. There is no
> reason to actually call it.

Yes. That was exactly my point. It's a sign that says DO NOT ENTER
(metaphorically). People are free to ignore it, because it is ignorable,
if (as you say below) people embed a testing.TB of some variety.


> (It's true that other code can implement the interface using
> inheritance, but that's OK because it can't cause that code to break.)

Yes.

Ian Lance Taylor

unread,
Sep 18, 2014, 8:26:27 PM9/18/14
to chai2010, Dan Kortschak, Jan Mercl, Islan Dberry, golang-nuts
On Thu, Sep 18, 2014 at 4:32 PM, chai2010 <chais...@gmail.com> wrote:
>
>
> 2014-09-19 5:26 GMT+08:00 Ian Lance Taylor <ia...@golang.org>:
>>
>> On Thu, Sep 18, 2014 at 1:50 PM, Dan Kortschak
>> <dan.ko...@adelaide.edu.au> wrote:
>> > Yes, aware of that. It is not called though as far as I can see.
>>
>> It's not called. Merely by existing it ensures that no other code can
>> implement the testing.TB interface. That is the goal. There is no
>> reason to actually call it.
>>
>> (It's true that other code can implement the interface using
>> inheritance, but that's OK because it can't cause that code to break.)
>
> Does the spec have docs for interface's private method ?

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

Ian

chai2010

unread,
Sep 18, 2014, 10:36:07 PM9/18/14
to Ian Lance Taylor, Dan Kortschak, Jan Mercl, Islan Dberry, golang-nuts
Thank you, Ian :) 


Ian



--

chai2010

unread,
Sep 18, 2014, 11:24:08 PM9/18/14
to Ian Lance Taylor, Dan Kortschak, Jan Mercl, Islan Dberry, golang-nuts
I create a new play code:

package main_test

import (
"fmt"
"testing"
)

func TestTB(t *testing.T) {
testTB(&TB{t})
}

func testTB(t testing.TB) {
t.Fatal("foo")
}

type TB struct {
testing.TB
}

func (p *TB) Fatal(args ...interface{}) {
fmt.Println("TB.Fatal disabled!")
}

Output:

TB.Fatal disabled!
PASS

The `testing.TB` is not a really private interface,
We can implementing the `testing.TB` interface.
Just like `TB.Fatal`.

Ian Lance Taylor

unread,
Sep 19, 2014, 10:37:04 AM9/19/14
to chai2010, Dan Kortschak, Jan Mercl, Islan Dberry, golang-nuts
On Thu, Sep 18, 2014 at 8:23 PM, chai2010 <chais...@gmail.com> wrote:
>
> The `testing.TB` is not a really private interface,
> We can implementing the `testing.TB` interface.
> Just like `TB.Fatal`.

The point is that if you do that, and we then add methods to
testing.TB, your code will not break.

If we did not have the private method, then you could write your own
type with your own methods that implemented everything in testing.TB,
and you could use your type, but then when we added methods to
testing.TB, your code would break.

In other words, exactly what the comment says:

// A private method to prevent users implementing the
// interface and so future additions to it will not
// violate Go 1 compatibility.

Ian
Reply all
Reply to author
Forward
Message has been deleted
0 new messages