Возможно ли, чтобы общий метод выводил его тип на основе класса, в котором он выполняется? Я использую модели CoreData NSManagedObject для хранения и извлечения локальных данных и сумел сделать все общее с легко читаемым и удобным способом, за исключением одного места. Если пользователь желает запросить локальную базу данных для извлечения списка объектов, он будет написать следующую строку:Infer Generic Type in Class Method with Swift
let posts: [Post] = Post.all()
Это будет правильно вернуть «все» почтовые объекты в базе данных, но синтаксис требует, чтобы тип ([Post]
) поверх вызова метода из самого класса Post
(Post.all()
), который чувствует излишнюю избыточность. Есть ли способ определить общий тип, просто вызвав метод all()
из класса Post
? Я полагаю, я мог бы просто создать глобальные функции для извлечения данных, например, так:
let posts: [Post] = all()
Это не чувствует себя почти так же читаемым, как было бы, если синтаксис следующим образом:
let posts = Post.all()
Точка попытки улучшить это так, чтобы любые разработчики, которые подбирали этот проект, могли быстро изучить структуру и стиль без особых усилий. Кроме того, это, мы надеемся, повысит общую читаемость кода в будущем, независимо от того, работает ли кто-то над этим или просто читает его по какой-то другой причине.
Для более глубокого, здесь немного больше информации о текущей структуре:
//Model.swift - The model base class. All models extend this class.
class Model: NSManagedObject {
/**
Some other stuff here
**/
//MARK: Fetch
internal class func fetch<T: Model>(predicate: NSPredicate? = nil) -> [T]? {
do {
if let request = NSFetchRequest.FromEntityName(self.entityName) { //Get entity with the name defined in the current class
request.predicate = predicate
if let result = try self.context?.executeFetchRequest(request) as? [T] {
return result
}
}
}
catch let error as NSError {
Log.Error("\(error)")
}
return nil
}
//MARK: Fetch general
class func all<T: Model>() -> [T]? {
if let result: [T] = self.fetch() {
return result
}
Log.warning("No \(self.entityName) found")
return nil
}
}
//Post.swift - An example model class. Extends Model.swift
class Post: Model {
//some fields
}
//Example view controller
class ViewController: UIViewController {
override func viewDidLoad() {
let posts: [Post] = Post.all()
//do stuff
}
}
Если кто-то имеет представление о том, пожалуйста, дайте мне знать. Вся помощь приветствуется!
Хорошая информация. Позвольте мне попробовать. Кроме того, RE: стиль кода - я это рассмотрю. Сама конвенция появилась только от работы в Свифте с другими людьми, в любом случае, где это был стандарт. Однако я не работаю с ними над этим проектом, поэтому я полагаю, что нет оснований устанавливать его, если языковые рекомендации указывают на другой путь. –
Одна вещь, которую я видел, когда я начинаю реализовывать это, заключается в том, что 'let request = Animal.fetchRequest' должен быть' let request = Animal.fetchRequest() '; В случае, если другие люди придут к этому ответу, это может помочь отредактировать ответ с этим исправлением. –