Compiler complains "undefined variable" when the variable is defined within a switch block

1,001 views
Skip to first unread message

AKU

unread,
Jan 12, 2014, 1:12:41 PM1/12/14
to golan...@googlegroups.com
Hi

I have a Form struct which holds a map of FormFields and a method to add FormField structs.

The method to add FormField looks as follows:
func (f *Form) addField(fieldtype,fieldname string) {
  switch fieldtype {
    case "text":
      ff := new(FormField_text)
    case "hidden":
      ff := new(FormField_hidden)
  }
  ff.name = fieldname
  // ... more fields to be filled and things to be done identical for all ff's
  f.fields[fieldname] = ff
}


Problem: The compiler says that "fieldname" can not be assigned because "ff" is not defined.

I can of course define "ff" outside the switch block using an interface:
func (f *Form) addField(fieldtype,fieldname string) {
  var ff FormFieldInterface
  switch fieldtype {
    case "text":
      ff = new(FormField_text)
    case "hidden":
      ff = new(FormField_hidden)
  }
  ff.name = fieldname

  // ... more fields to be filled and things to be done identical for all ff's
  f.fields[fieldname] = ff
}


Problem: Now the compiler complains that the interface FormFieldInterface has no field "name". That's correct, of course because I can not define the fields for the interface but only for the structs that implement that interface.

Obviously I do not want to repeat assignements and actions for the ff's inside each switch case. But right now this seems to be the only working solution.
Can anybody help me what I could do instead?

I have been programmed PHP and Javascript so far. Therefore, I am sorry if this is a beginners question. All hints are highly appreciated.

Adrian

Nick Patavalis

unread,
Jan 12, 2014, 1:31:34 PM1/12/14
to golan...@googlegroups.com
The compiler is, obviously, right. When it sees

  ff.name = fieldname

the compiler must know (or be able to deduce without ambiguity) the type of ff. This is not the case with your code.

The only solution I can see (without repeating the assignment to "ff.name") is to add a "Name" method to the FormFieldInterface that sets the corresponding field (or fields) in the respective concrete types. if you think of it, this is the only conceptually-correct approach: Different structures, with different implementation, both providing the same method. The fact that you have two structures that HAPPEN to both have a field with the same name, does not make it the same field.

/npat 

AKU

unread,
Jan 12, 2014, 1:54:56 PM1/12/14
to golan...@googlegroups.com
Thank you for the quick answer.

You are right. In fact, the struct fields ARE different depending on the FormField type.
I will try using an init() method which I can implement specifically for each FormField type.

It seems I still have too much PHP in my mind ;-).

Thank you for helping me out.

Adrian

minux

unread,
Jan 12, 2014, 2:00:23 PM1/12/14
to AKU, golang-nuts


On Jan 12, 2014 1:54 PM, "AKU" <kueh...@gmail.com> wrote:
> You are right. In fact, the struct fields ARE different depending on the FormField type.
> I will try using an init() method which I can implement specifically for each FormField type.

another way is to extract these common fileds out into another "common" struct, implement the required Set method for it and then embed the common struct into every FormField struct so that you only need to write the Set method once.

Matt Harden

unread,
Jan 12, 2014, 8:49:24 PM1/12/14
to AKU, golan...@googlegroups.com
You could initialize the structs when you create them.

func (f *Form) addField(fieldtype,fieldname string) {
  switch fieldtype {
    case "text":
      ff := &FormField_text{name: fieldname}
    case "hidden":
      ff := &FormField_hidden{name: fieldname}

  }
  ff.name = fieldname
  // ... more fields to be filled and things to be done identical for all ff's 
  f.fields[fieldname] = ff
}
--
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/groups/opt_out.

Adrian Kuehnis

unread,
Jan 13, 2014, 12:06:47 AM1/13/14
to golan...@googlegroups.com, AKU
Thank you, this works perfectly.

func (f *Form) addField(fieldtype,fieldname string) {
  var ff FormFieldInterface
  switch fieldtype {
    case "text":
      ff = &FormField_text{name:fieldname}

    case "hidden":
      ff = &FormField_hidden{name:fieldname}
  }
  // ... more ff methods to be called
  f.fields[fieldname] = ff
}


Thank you for your help!

Reply all
Reply to author
Forward
0 new messages