Question: What is an appropriate way to solve the following example with swift?

I know because of type erasure that you cannot assign `StructB` to `item2` in the constructor. In other languages like *Java* I would solve the problem by not having a generic class parameter `T` in the `Container` struct but let vars `item` and `item2` just be the type of `ProtocolA` (like `var item2: ProtocolA`).
This is not allowed by swift: *Protocol 'ProtocolA' can only be used as a generic constraint because it has Self or associated type requirements*

I worked through [this](https://docs.swift.org/swift-book/LanguageGuide/Generics.html) section of swifts documentation about generics but so far I was not able to adapt a solution for my simple problem:

```swift
protocol ProtocolA {
    associatedtype B

    func foo() -> B
}

struct StructA: ProtocolA {
    typealias B = String

    func foo() -> String {
        "Hello"
    }
}

struct StructB: ProtocolA {
    typealias B = Double

    func foo() -> Double {
        0.0
    }
}

struct Container<T: ProtocolA> {

    var item: T
    var item2: T

    init(item: T) {
        self.item = item
        self.item2 = StructB() // err: Cannot assign value of type 'StructB' to type 'T'
    }
}

```

I also want to know how a solution could look if I do not want to specify a generic type parameter at all for the container struct. So that I could write the following:

```swift
func test() {
    let container = Container(StructA()) // no type given
}

```

Answer: 
For the problem as described, the answer is very straightforward:

```
struct Container<T: ProtocolA> {

    var item: T
    var item2: StructB // This isn't T; you hard-coded it to StructB in init

    init(item: T) {
        self.item = item
        self.item2 = StructB()
    }
}

let container = Container(item: StructA()) // works as described

```

I get the feeling that there's something deeper to this question, which is why Alexander was asking for more context. As written, the question's answer seems too simple, so some of us assume that there's more that you didn't explain, and we want to avoid a round of "here's the answer" followed by "that's not what I meant."

As you wrote it, you try to force `item` and `item2` to have the same type. That's obviously not what you mean because `T` is given by the caller, and `item2` is always StructB (which does not have to equal `T`, as the error explains).

Is there another way you intend to call this code? It's unclear what code that calls `foo()` would look like. Do you have some other way you intend to initialize Container that you didn't explain in your question?

Maybe you want two different types, and you just want StructB to be the default? In that case, it would look like (based on Ptit Xav's answer):

```
struct Container<T: ProtocolA, U: ProtocolA> {

    var item: T
    var item2: U

    // Regular init where the caller decides T and U
    init(item: T, item2: U) {
        self.item = item
        self.item2 = item2
    }

    // Convenience where the caller just decides T and U is default
    init(item: T) where U == StructB {
       self.init(item: item, item2: StructB())
    }
}

```

The `where U == StructB` allows you to make a default type for U.
The only way to do something like you want is :

```
struct Container<T: ProtocolA,U: ProtocolA> {

    var item: T
    var item2: U

    init(item: T, item2: U) {
        self.item = item
        self.item2 = item2
    }
}

```