我正在尝试使用Vapor和Fluent的服务器端Swift项目。这个项目的想法是跟踪运动员及其训练计划和训练。尝试以协议为导向,我有一个名为“锻炼”的协议,然后是符合“锻炼”的各种类,如“跑步”,“游泳”等。
Workout.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'不符合协议'可解码'
类型'TrainingPlan'不符合协议'Encodable'
将Workout.swift更改为:
protocol Workout: Codable {
var title: String { get set }
var duration: Int { get set }
}
无法解决错误。
使用Fluent处理此问题的正确方法是什么,同时在我的数据建模中仍然保持面向协议?谢谢!
更新(6/20/18):
在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”
答案 0 :(得分:0)
您需要做
swift
migrations.add(model: TrainingPlan<ConcreteWorkoutType>.self, database: .psql)
因此,编译器在编译代码时就知道泛型是什么