Я довольно новичок в языке программирования Swift. Я пытаюсь создать функцию util, которая принимает универсальный.
class Utils {
static func formatArtists<T: ArtistDetails>(_ artists: [T]) -> String {
return artists.map({ artist in
return artist.name
}).joined(separator: ", ")
}
}
Я получаю две ошибки для этого фрагмента кода
Type 'T' constrained to non-protocol, non-class type 'ArtistDetails'
Value of type 'T' has no member 'name'
Я думаю, мне нужно продлить protocol или что-то в этом роде.
Я хочу иметь возможность вызывать вспомогательную функцию следующим образом.
Text(Utils.formatArtists(track.artists))
Text(Utils.formatArtists(mix.artists))
И track, и mix художники используют фрагмент ArtistDetails.
Сведения об исполнителе генерируются библиотекой Apollo swift
public struct ArtistDetails: GraphQLFragment {
/// The raw GraphQL definition of this fragment.
public static let fragmentDefinition: String =
"""
fragment ArtistDetails on Artist {
__typename
id
name
}
"""
public static let possibleTypes: [String] = ["Artist"]
public static var selections: [GraphQLSelection] {
return [
GraphQLField("__typename", type: .nonNull(.scalar(String.self))),
GraphQLField("id", type: .nonNull(.scalar(GraphQLID.self))),
GraphQLField("name", type: .nonNull(.scalar(String.self))),
]
}
public private(set) var resultMap: ResultMap
public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}
public init(id: GraphQLID, name: String) {
self.init(unsafeResultMap: ["__typename": "Artist", "id": id, "name": name])
}
public var __typename: String {
get {
return resultMap["__typename"]! as! String
}
set {
resultMap.updateValue(newValue, forKey: "__typename")
}
}
public var id: GraphQLID {
get {
return resultMap["id"]! as! GraphQLID
}
set {
resultMap.updateValue(newValue, forKey: "id")
}
}
public var name: String {
get {
return resultMap["name"]! as! String
}
set {
resultMap.updateValue(newValue, forKey: "name")
}
}
}
protocol GraphQLFragment : GraphQLSelectionSet
Спасибо
Обновлено с помощью ArtistDetails





В Swift вы можете написать это так:
extension Collection where Element == ArtistDetails {
var formatted: String {
map(\.name).joined(separator: ", ")
}
}
Text(track.artists.formatted)
Вы не можете написать общий вид, например <T: ArtistDetails>, потому что ArtistDetails — это структура, поэтому она не поддерживает подклассы и не является протоколом, поэтому T не может быть любым типом, реализующим протокол или «являющимся» ArtistDetails. Нет необходимости в классе Utils - если вам когда-нибудь понадобится такое пространство имен, перечисление (без регистров) будет предпочтительным как тип, который не может быть создан.
Спасибо, это точно сработает. Хотя получить этот тип вопроса Type '(S) -> S.FormatOutput' cannot conform to 'StringProtocol'
Мы не видим ваш код, но эта ошибка говорит о том, что у вас есть что-то вроде функция (от S до S.FormatOuput), а функция не является строкой, но если вы вызовете() ее, то у вас будет строка
не могли бы вы показать код для
ArtistDetails?