2

I am trying to have nil for zeroth index element and rest will have value of Generic type T which is Comparable.

So when I initialise it will nil it works as expected

struct Container<T: Comparable> {
    var container = [T?]()

    init() {
        container.append(nil)
    }
}

but when I do it with an integer say 0, I get ambiguous reference

struct Container<T: Comparable> {
    var container = [T?]()

    init() {
        container.append(0)
    }
} 

Playground execution failed: error: Algorithms.playground:7:9: error: ambiguous reference to member 'append'
        container.append(0)
        ^~~~~~~~~

I want to understand why this error is occurring?

1
  • 1
    T is not necessary Int – it could be String, and 0 cannot be added to a [String?]. Commented Apr 6, 2017 at 9:57

2 Answers 2

2

The issue is that T: Comparable does not necessarily mean Int, it means ANY value that conforms to Comparable, which includes String, Float, Bool, and the thousands of custom structs other programmers have written for their own projects.

Since 0 is not a valid value for all of these Structs, you essentially have one of two issues:

1) Do I actually just want the Container to always use Int - in which case:

struct Container
{
    var container: [Int?]

    init()
    {
        container = [nil]
    }
}

var a = Container()
a.container.append (0)

2) Why am I using 0, when I mean nil

struct Container<T: Comparable>
{
    var container: [T?]

    init()
    {
        container = [nil]
    }
}

var a = Container<Int>()
a.container.append (0)
Sign up to request clarification or add additional context in comments.

Comments

1

T can by any comparable type (String, a custom type, ...), and initializing it from 0 is not generally possible.

You could require that T can be created from an integer literal, this covers all integer and floating point types:

struct Container<T: Comparable> where T: ExpressibleByIntegerLiteral {
    var container = [T?]()

    init() {
        container.append(0)
    }
} 

Or provide a separate append() method:

struct Container<T: Comparable> {
    var container = [T?]()

    init() {
        container.append(nil)
    }

    mutating func append(_ newElement: T) {
        container.append(newElement)
    }
} 

var c = Container<Int>()
c.append(0)

4 Comments

doesn't this defeat the purpose of having container as a generic type?
@RajeevBhatia: It is still generic, just for a restricted set of types. If you don't restrict it then append(0) makes no sense.
@MartinR I though Array should have append method and if I am providing T type literal then it should behave as it supposed to.
@Rahul: Then how should let c = Container<String>() work? What do you expect it to do?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.