在 Swift 中使用 Apollo Graphql Fragments 作为通用类型

Using Apollo Graphql Fragments as generic types in Swift

我对 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))

trackmix 艺术家都使用 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

谢谢

在Swift中你可能更喜欢这样写

extension Collection where Element == ArtistDetails {
    var formatted: String {
        map(\.name).joined(separator: ", ")
    }
}

Text(track.artists.formatted)

你不能写一个像 <T: ArtistDetails> 这样的泛型,因为 ArtistDetails 是一个结构,所以不支持 subclassing,也不是协议,所以 T 不能是任何实现协议或“是”ArtistDetails 的类型。不需要 Utils class - 如果您需要像这样的命名空间,枚举(没有大小写)将被首选作为无法实例化的类型。