import Foundation protocol MyDecodable { init(decode bytes: Data) } enum Message { protocol Request { associatedtype Response: MyDecodable func encodeToData(_ body: inout Data) } } struct FooRequest: Message.Request { struct Response: MyDecodable { var message: String init(decode bytes: Data) { message = String(data: bytes, encoding: .utf8) ?? "error!" } } func encodeToData(_ body: inout Data) { body.append(contentsOf: "Foo".utf8) } } struct BarRequest: Message.Request { struct Response: MyDecodable { var message: String init(decode bytes: Data) { message = String(data: bytes, encoding: .utf8) ?? "error!" } } func encodeToData(_ body: inout Data) { body.append(contentsOf: "Bar".utf8) } } private func send<each Request: Message.Request>(_ messages: repeat each Request) async throws -> (repeat (each Request).Response) { var body: Data = .init() for message in repeat each messages { message.encodeToData(&body) body.append(contentsOf: "\0".utf8) } let responseBody = body // 本当はなにか別の送信処理 var responseSubSections = responseBody.split(separator: "\0".utf8).makeIterator() func decodeBytes<R: Message.Request>(requestType: R.Type) -> R.Response { guard let next = responseSubSections.next() else { fatalError("レスポンス個数不一致") } return R.Response.init(decode: next) } return (repeat decodeBytes(requestType: (each Request).self)) } let (fooRes, barRes) = try await send(FooRequest(), BarRequest()) print(fooRes.message) print(barRes.message)