> case foo, *foo:
> return t.String()
> t.String undefined (type Foo has no field or method String)
When you use a single type in a case, a new variable with the same name
is introduced with that type. When you use multiple types in a case,
this does not happen, because it is not clear what the type should be.
So here t has type Foo, and you are asking for the String method of Foo,
but it doesn't have one.
Ian
Ian
Yes.
As Ian said, with `case A, B`, the variable (`t` above) is bound to
the /general/ type of f, not any of the types A and B. (How would you
choose which of A and B to bind?)
> so the logic should really be "comparing t's type
> to each of the type(s) in cases and if it evaluate to true, then exec the
> statement.
f's type, not t's.
> With "case foo, *foo", I would assume the compiler should
> generate the code to iterate the types provided and see if any one of them
> is the same as t.
Yes. But the /static type/ of t is the same as that of f.
> I think writing code like the Workable() case is quite awkward, I should be
> able to provide types that known to have the required methods with just one
> case clause instead of enumerating them individually.
Define an interface with those methods and use it as the
case value.
> Is there a reason it is technically impossible to implement?
No. But mere technical non-impossibility isn't enough.
Chris
--
Chris "allusive" Dollin
On 25 August 2011 08:17, Yongjian Xu <i3dm...@gmail.com> wrote:Yes.
> On Wed, Aug 24, 2011 at 10:38 AM, Ian Lance Taylor <ia...@google.com> wrote:
>>
>> i3dmaster <i3dm...@gmail.com> writes:
>>
>> > case foo, *foo:
>> > return t.String()
>>
>> > t.String undefined (type Foo has no field or method String)
>>
>> When you use a single type in a case, a new variable with the same name
>> is introduced with that type. When you use multiple types in a case,
>> this does not happen, because it is not clear what the type should be.
>> So here t has type Foo, and you are asking for the String method of Foo,
>> but it doesn't have one.
>
> Hmm...Sorry I still don't get it. f has type Foo but with t := f.(type), t
> should have the actual type value (like type case in other lang. Am I
> understanding it wrong?)
As Ian said, with `case A, B`, the variable (`t` above) is bound to
the /general/ type of f, not any of the types A and B. (How would you
choose which of A and B to bind?)
f's type, not t's.
> so the logic should really be "comparing t's type
> to each of the type(s) in cases and if it evaluate to true, then exec the
> statement.
Yes. But the /static type/ of t is the same as that of f.
> With "case foo, *foo", I would assume the compiler should
> generate the code to iterate the types provided and see if any one of them
> is the same as t.
Define an interface with those methods and use it as the
> I think writing code like the Workable() case is quite awkward, I should be
> able to provide types that known to have the required methods with just one
> case clause instead of enumerating them individually.
case value.
No. But mere technical non-impossibility isn't enough.
> Is there a reason it is technically impossible to implement?
`t` only gets to have one type, and the choices are the type of f,
the type A, or the type B. Whichever of A and B it picks, it's wrong
(in general) if f actually has the other one. So neither is the right
choice, so it must be the static type of f.
>> Yes. But the /static type/ of t is the same as that of f.
>
> But with each case, t gets bound to those literal types...
When there's only one type in the case, not if there's more.
> "The TypeSwitchGuard may include a short variable declaration. When that
> form is used, the variable is declared in each clause. In clauses with a
> case listing exactly one type, the variable has that type; otherwise, the
> variable has the type of the expression in the TypeSwitchGuard.
> "
> If I understand this statement correctly, t's actual type changes in each
> case.
Each case has a t with the appropriate type.
>> > I think writing code like the Workable() case is quite awkward, I should
>> > be
>> > able to provide types that known to have the required methods with just
>> > one
>> > case clause instead of enumerating them individually.
>>
>> Define an interface with those methods and use it as the
>> case value.
>
> Ok good tips. Maybe this is the idiomatic way in Go to express this logic.
> So I could just
> case Bar:
> blah()
> case Foo:
> blah()
> and just switch on interfaces, not actual types.
case MyInterfaceType:
t.TheAppropriateMethod()
You're not intereted in Bar vs Foo, but just the common interface
they have.
>> > Is there a reason it is technically impossible to implement?
>>
>> No. But mere technical non-impossibility isn't enough.
>
> Ok, so what are the concerns? performance? expressiveness? readability?...
Mere technical non-impossibility isn't enough to adopt some
feature F; there has to be enough value in doing so.
Performance,expressiveness, and readability are some of the
things that play into it. Go puts great value on simplicity. And
features compete for a limited resource -- developer time.