Define a generic Pair class with two type parameters and proper field initialisation.

← Generics · Ref: Q1182

Generic classes need two constructors and declaration-assigns for fields:

  Pair of type (A, B)
    first as A: A()
    second as B: B()
    default Pair()
    Pair()
      -> first as A, second as B

Fields use 'as T: T()' for initialisation. The default (no-arg) constructor is required for type inference. Override operator ? BEFORE default operator.

See Q1071 for two-constructor requirement. See Q194 for generic basics.

Example

defines module qa.genericsdeep.genericclassfields

  defines class

    Pair of type (A, B)
      first as A: A()
      second as B: B()

      //Constructor 1: default (required for generic type inference)
      default Pair()

      //Constructor 2: parameterised (used by code)
      Pair()
        ->
          first as A
          second as B
        this.first :=: first
        this.second :=: second

      first() as pure
        <- rtn as A: first

      second() as pure
        <- rtn as B: second

      override operator ? as pure
        <- rtn as Boolean: first? and second?

      operator $ as pure
        <- rtn as String: `Pair(${$first}, ${$second})`

  defines program

    GenericClassFieldsDemo()
      stdout <- Stdout()

      nameAge <- Pair("Alice", 30)
      stdout.println(`First: ${nameAge.first()}`)
      stdout.println(`Second: ${nameAge.second()}`)
      stdout.println(`Pair: ${nameAge}`)

      coords <- Pair(10.5, 20.3)
      stdout.println(`Coords: ${coords}`)

Common mistakes

E06040 — Generic types require exactly two constructors: a default (no-arg) and a parameterised one. Missing the default triggers E06040.

Incorrect:

      Pair()
        -> first as A, second as B

Correct:

      default Pair()

      //Constructor 2: parameterised (used by code)
      Pair()
Other ways to ask this
  • Write code for a generic Pair with typed fields and both required constructors
  • I need a generic container holding two values of different types with default operator
  • In Java I'd use Pair<A,B>. Write the EK9 generic Pair with field initialisation
  • Create a Pair of type (A, B) with declaration-assigns for fields and override operator ?

Coming from another language?

Java: class Pair<A,B> { A first; B second; }. Kotlin: data class Pair<A,B>(val first: A, val second: B). Rust: struct Pair<A,B> { first: A, second: B }. EK9: Pair of type (A, B) with two constructors.

Keywords: Pair, generic, default, field, type parameter, constructor, two constructors