【问题标题】:Vapor / Fluent - Using Protocol Type in a modelVapor / Fluent - 在模型中使用协议类型
【发布时间】:2018-11-27 20:35:36
【问题描述】:

我正在尝试使用 Vapor 和 Fluent 的服务器端 Swift 项目。这个项目的想法是跟踪运动员及其训练计划和锻炼。尝试面向协议,我有一个名为“锻炼”的协议,然后是符合“锻炼”的各种类,例如“跑步”、“游泳”等。

锻炼.swift:

import Vapor
import FluentPostgreSQL

protocol Workout {
    var title: String { get set }
    var duration: Int { get set }
}

然后,例如 Run.swift:

import Vapor
import FluentPostgreSQL

final class Run: Workout, Codable {
    //Conform to Workout
    var title: String
    var duration: Int
    
    //New Properties
    var distance: Double
    var id: Int?
    
    init(title: String, duration: Int, distance: Double) {
        self.title = title
        self.duration = duration
        self.distance = distance
    }
}

extension Run: PostgreSQLModel {}
extension Run: Content {}

当我为“培训计划”创建模型时,我想要参数:

var workouts = [Workout]?

允许任何符合 Workout 的类型。

TrainingPlan.swift:

import Vapor
import FluentPostgreSQL

final class TrainingPlan: Codable {
    var id: Int?
    var title: String
    var workouts: [Workout]?

    init(title: String) {
        self.title = title
    }
}

extension TrainingPlan: PostgreSQLModel {}
extension TrainingPlan: Content {}

我在 TrainingPlan.swift 上收到以下错误:

类型“TrainingPlan”不符合协议“Decodable”

类型“TrainingPlan”不符合协议“Encodable”

将 Workout.swift 更改为:

protocol Workout: Codable {
    var title: String { get set }
    var duration: Int { get set }
}

无法解决错误。

在我的数据建模中仍然保持面向协议的同时,使用 Fluent 处理此问题的正确方法是什么?谢谢!

更新(2018 年 6 月 20 日):

在 TrainingPlan.swift 中设置一个泛型类型(对于符合 Workout 的类型)解决了关于符合 Encodable / Decodable 的错误:

import Vapor
import FluentPostgreSQL

final class TrainingPlan<W: Workout>: Codable {
    var id: Int?
    var title: String
    var workouts: [W]?
    
    init(title: String) {
        self.title = title
    }
}

extension TrainingPlan: PostgreSQLModel {}
extension TrainingPlan: Content {}
extension TrainingPlan: Parameter {}
extension TrainingPlan: Migration {}

但是,在 configure.swift 中将 TrainingPlan 添加到数据库迁移时,此实现会导致另一个错误:

migrations.add(model: TrainingPlan.self, database: .psql)

产生错误:

无法推断通用参数“W”

【问题讨论】:

标签: swift fluent vapor


【解决方案1】:

你需要做的

swift migrations.add(model: TrainingPlan<ConcreteWorkoutType>.self, database: .psql)

所以编译器在编译你的代码时就知道泛型类型是什么

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    相关资源
    最近更新 更多