Skip to content
This repository has been archived by the owner on Apr 15, 2024. It is now read-only.

Translate constructor of structs #70

Open
sgade opened this issue Jul 7, 2020 · 6 comments
Open

Translate constructor of structs #70

sgade opened this issue Jul 7, 2020 · 6 comments
Labels
enhancement New feature or request

Comments

@sgade
Copy link
Contributor

sgade commented Jul 7, 2020

Is your feature request related to a problem? Please describe.

Using a struct to manage data, in Swift you can add an initialiser for storing the properties:

public struct FoodSpecial {
    public let id: String
    
    public let title: String
    public let subtitle: String
    public let price: Double
    
    public init(title: String, subtitle: String, price: Double) {
        self.id = UUID().uuidString
        
        self.title = title
        self.subtitle = subtitle
    }
}

this is translated by Gryphon to a data class with a constructor:

data class FoodSpecial(
    val id: String,
    val title: String,
    val subtitle: String,
    val price: Double
) {
    constructor(
        title: String,
        subtitle: String,
        price: Double)
    {
        this.id = UUID().toString()
        this.title = title
        this.subtitle = subtitle
        this.price = price
    }
}

Describe the solution you'd like

According to my Kotlin knowledge, the best way to implement the behavior would be to use default values. See this example:

data class FoodSpecial(
    val id: String = UUID().toString(),
    val title: String,
    val subtitle: String,
    val price: Double
)

Describe alternatives you've considered

As data classes cannot have constructors, this seems to be the best way to approach this.

Additional context

none

@sgade sgade added the enhancement New feature or request label Jul 7, 2020
@sgade
Copy link
Contributor Author

sgade commented Jul 7, 2020

This actually leads to Kotlin build errors: Primary constructor call expected and Val cannot be reassigned.
image

@vinivendra
Copy link
Owner

Hi @sgade, thanks for filing this issue (and the others).

We still need to figure out a more comprehensive solution for initializers everywhere, but perhaps we can find (or implement) a solution for your use case in the meantime.

Would you be OK with using something like this in Swift?

public struct FoodSpecial {
    public let id: String = "a"
    public let title: String
    public let subtitle: String
    public let price: Double
}

// OK
let food = FoodSpecial(title: "", subtitle: "", price: 0)

// Not allowed by Swift:
// let otherFood = FoodSpecial(id: "2", title: "", subtitle: "", print: 0)

This currently gets translated to

data class FoodSpecial(
    val id: String = "a",
    val title: String,
    val subtitle: String,
    val price: Double
)

fun main(args: Array<String>) {
    val food: FoodSpecial = FoodSpecial(title = "", subtitle = "", price = 0.0)
}

which works in Kotlin.

If this doesn't work for you, let me know why and we'll figure something out.

@sgade
Copy link
Contributor Author

sgade commented Jul 7, 2020

Thanks for your quick reply!
Your suggestions fine works for me and is suitable at the moment, so I'll go with that.

I like the idea of using warnings to inform the user that a certain feature is not (yet) support. Do you think it would make sense do add a warning for this case? It might refer the user to using the possible fix you suggested here.

@vinivendra
Copy link
Owner

Yeah, I don't think we currently support any initializers in structs, so it would make sense to raise warnings when we find them.

@sgade
Copy link
Contributor Author

sgade commented Jul 7, 2020

I just noticed again why I was using explicit initialisers: The structs I am translating are located in a Swift package and therefore need an explicit public init to be accessible by my app project.

Now I could create something business-y like Factories. I guess in my particular case there is not disadvantage in using classes instead.

@vinivendra
Copy link
Owner

Ok! I'm gonna implement the warnings for now, but I'll leave this issue open until the initializers are properly fixed.

You could probably ignore your Swift initializer with // gryphon ignore and manually add a Kotlin constructor with // gryphon insert: (like we do here) if you prefer to use structs.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants