Combine рдореЗрдВ рдЕрдкрдирд╛ Publisher рдмрдирд╛рдПрдБ


рдЖрдЬ рдореИрдВ рдЖрдкрдХреЛ рдПрдкреНрдкрд▓ рдХреЗ рдирдП рдХреЙрдореНрдмрд┐рдиреЗрд╢рди рдврд╛рдВрдЪреЗ рдореЗрдВ рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдкреНрд░рдХрд╛рд╢рдХ рдмрдирд╛рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдмрддрд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред


рдФрд░ рдЗрд╕рд▓рд┐рдП, рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдпрд╛рдж рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдЧрдардмрдВрдзрди рдХреЗ рдореВрд▓ рднрд╛рдЧ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН рдкреНрд░рдХрд╛рд╢рдХ, рд╕рджрд╕реНрдпрддрд╛, рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ред


  • рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдкреНрд░рдХрд╛рд╢рдХ рд╕реЗ рдЬреБрдбрд╝рддрд╛ рд╣реИ
  • рдкреНрд░рдХрд╛рд╢рдХ рд╕рджрд╕реНрдпрддрд╛ рд╕рджрд╕реНрдп рдХреЛ рднреЗрдЬрддрд╛ рд╣реИ
  • рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рд╕рдмреНрд╕рдХреНрд░рд┐рдкреНрд╢рди рд╕реЗ рдПрди рдорд╛рди рдорд╛рдВрдЧрддрд╛ рд╣реИ
  • рдкреНрд░рдХрд╛рд╢рдХ рдПрди рдорд╛рди рдпрд╛ рдХрдо рднреЗрдЬрддрд╛ рд╣реИ
  • рдкреНрд░рдХрд╛рд╢рдХ рдПрдХ рдкреВрд░реНрдг рд╕рд┐рдЧреНрдирд▓ рднреЗрдЬрддрд╛ рд╣реИ

рдкреНрд░рдХрд╛рд╢рдХ


рддреЛ рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИ рд╣рдорд╛рд░рд╛ рдкрдмреНрд▓рд┐рд╢рд░ рдмрдирд╛рдирд╛ред Apple рдкреНрд░рд▓реЗрдЦрди рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реБрдП, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдкреНрд░рдХрд╛рд╢рдХ рдПрдХ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╣реИред


public protocol Publisher { associatedtype Output associatedtype Failure : Error func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input } 

рдЬрд╣рд╛рдВ рдЖрдЙрдЯрдкреБрдЯ рдЗрд╕ рдкреНрд░рдХрд╛рд╢рдХ рджреНрд╡рд╛рд░рд╛ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рдорд╛рдиреЛрдВ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ, рд╡рд┐рдлрд▓рддрд╛ рд╡рд┐рдлрд▓рддрд╛ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬрд┐рд╕реЗ рддреНрд░реБрдЯрд┐ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред


рдФрд░ рдкреНрд░рд╛рдкреНрдд рд╕рдорд╛рд░реЛрд╣ (_: рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░), рдЬрд┐рд╕реЗ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рд╕рджрд╕реНрдпрддрд╛ (_ :) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗред


рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рдкреНрд░рдХрд╛рд╢рдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ред


 struct FibonacciPublisher: Publisher { typealias Output = Int typealias Failure = Never } 

рдЪреВрдВрдХрд┐ рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рд╕рдВрдЦреНрдпрд╛рдПрдБ рд╣реЛрддреА рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЖрдЙрдЯрдкреБрдЯ рдХрд╛ рдкреНрд░рдХрд╛рд░ Int рд╣реЛрдЧрд╛, рдФрд░ рд╡рд┐рдлрд▓рддрд╛ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреА Never рд╣реЛрдЧреА, рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкреНрд░рдХрд╛рд╢рдХ рдХрднреА рд╡рд┐рдлрд▓ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред


рд▓рдЪреАрд▓реЗрдкрди рдХреЗ рд▓рд┐рдП, рд╣рдо рдЙрди рддрддреНрд╡реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рд╕реАрдорд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдЕрдкрдиреЗ рдкреНрд░рдХрд╛рд╢рдХ рдХреЗ рдХреБрдЫ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЗрд╕ рдорд╛рди рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдФрд░ рд▓рдкреЗрдЯрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


 struct FibonacciConfiguration { var count: UInt } 

рдЖрдЗрдП рдЗрд╕ рдХреЛрдб рдкрд░ рдПрдХ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ, var count: UInt рдПрдХ рдЕрдЪреНрдЫреЗ рд╡рд┐рдХрд▓реНрдк рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдореЗрдВ рдЯрд╛рдЗрдк UInt рдХреЗ рдорд╛рдиреНрдп рдорд╛рдиреЛрдВ рдХреА рд╕реАрдорд╛ рддрдХ рд╕реАрдорд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рднреА рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрджрд┐ рд╣рдо рдЕрднреА рднреА рдЕрд╕реАрдорд┐рдд рдЕрдиреБрдХреНрд░рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдХреНрдпрд╛ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВред


UInt рдХреЗ рдмрдЬрд╛рдп, рд╣рдо Subscribers.Demand рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдХрд┐ Combine рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдЗрд╕реЗ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рд╕реЗ рдкреНрд░рдХрд╛рд╢рдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рдХрд╛рд╢рдХ рдХреЛ рднреЗрдЬреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╕рд░рд▓ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдпрд╣ рддрддреНрд╡реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ, рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рджреНрд╡рд╛рд░рд╛ рдХрд┐рддрдиреЗ рддрддреНрд╡реЛрдВ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЕрд╕реАрдорд┐рдд - рд╕реАрдорд┐рдд рдирд╣реАрдВ, рдХреЛрдИ рдирд╣реАрдВ - рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ, рдЕрдзрд┐рдХрддрдо (рдПрди) - рдПрди рдмрд╛рд░ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВред


  public struct Demand : Equatable, Comparable, Hashable, Codable, CustomStringConvertible { public static let unlimited: Subscribers.Demand public static let none: Subscribers.Demand ///  Demand.max(0) @inlinable public static func max(_ value: Int) -> Subscribers.Demand .... } 

рд╣рдо рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдП рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдмрджрд▓рддреЗ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рдСрдирдлрд┐рдЧрд░реЗрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВред


 struct FibonacciConfiguration { var count: Subscribers.Demand } 

рдЪрд▓рд┐рдП рд╣рдо рд╡рд╛рдкрд╕ рдкреНрд░рдХрд╛рд╢рдХ рдХреЗ рдкрд╛рд╕ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рд╛рдкреНрдд (_: рд╕рдмрд╕реНрдХреНрд░рд╛рдЗрдмрд░) рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ, рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рдкреНрд░рдХрд╛рд╢рдХ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╡рд┐рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдФрд░ рд╡рд╣ рд╕рдмреНрд╕рдХреНрд░рд┐рдкреНрд╢рди рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИ, рдкреНрд░рдХрд╛рд╢рдХ рдХреЛ рд╕рдмреНрд╕рдХреНрд░рд┐рдкреНрд╢рди рдмрдирд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рд╕рдмреНрд╕рдХреНрд░рд┐рдкреНрд╢рди рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред


  func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input { let subscription = FibonacciSubscription(subscriber: subscriber, configuration: configuration) subscriber.receive(subscription: subscription) } 

рдпрд╣ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рдХрд╛рд╢рдХ рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдорд╛рдиреЛрдВ рдХреЛ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЗ рдЗрдирдкреБрдЯ рдореВрд▓реНрдпреЛрдВ (рдЖрдЙрдЯрдкреБрдЯ == S.Input) рд╕реЗ рдореЗрд▓ рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╣реИред рдпрд╣ рдкреНрд░рдХрд╛рд╢рдХ рдФрд░ рдЧреНрд░рд╛рд╣рдХ рдХреЛ "рдХрдиреЗрдХреНрдЯ" рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред


рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╣реА, рдПрдХ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди рд╕рджрд╕реНрдпрддрд╛ рдмрдирд╛рдПрдВ, рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рд╣рдо рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рд╕рдмреНрд╕рдХреНрд░рд┐рдкреНрд╢рди рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рд╣рдорд╛рд░рд╛ рдкреНрд░рдХрд╛рд╢рдХ рддреИрдпрд╛рд░ рд╣реИ, рдЕрдВрдд рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣реИ:


 struct FibonacciPublisher: Publisher { typealias Output = Int typealias Failure = Never var configuration: FibonacciConfiguration func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input { let subscription = FibonacciSubscription(subscriber: subscriber, configuration: configuration) subscriber.receive(subscription: subscription) } } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдкреНрд░рдХрд╛рд╢рдХ рдХреЗ рдкрд╛рд╕ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рдЕрдиреБрдХреНрд░рдо рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИ; рд╕рднреА рддрд░реНрдХ рд╕рджрд╕реНрдпрддрд╛ рд╡рд░реНрдЧ - рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди рдореЗрдВ рд╣реЛрдВрдЧреЗред


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди рдХреНрд▓рд╛рд╕ рд╕рдмреНрд╕рдХреНрд░рд┐рдкреНрд╢рди рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдЧрд╛, рдЖрдЗрдП рдЗрд╕ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рджреЗрдЦреЗрдВред


 public protocol Subscription : Cancellable, CustomCombineIdentifierConvertible { func request(_ demand: Subscribers.Demand) } 

рдЕрдиреБрд░реЛрдз (_: Subscribers.Demand) рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рдХрд╛рд╢рдХ рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдЕрдзрд┐рдХ рдореВрд▓реНрдп рднреЗрдЬ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рдкрджреНрдзрддрд┐ рдореЗрдВ рд╣реИ рдХрд┐ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛ рднреЗрдЬрдиреЗ рдХрд╛ рддрд░реНрдХ рдХреНрдпрд╛ рд╣реЛрдЧрд╛ред
рд╣рдореЗрдВ рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдФрд░ рд░рджреНрдж () рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


 public protocol Cancellable { func cancel() } 

рдФрд░ рдмрд╕ CustomCombineIdentifierConvertible рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВ рдФрд░ рдХреЗрд╡рд▓ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрдиреАрдп CombIdentifier рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВред


 public protocol CustomCombineIdentifierConvertible { var combineIdentifier: CombineIdentifier { get } } 

рдпрд╣рд╛рдБ рдПрдХ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рд╣реИ, рдпрджрд┐ рдЖрдк Combine рдореЗрдВ CustomCombineIdentifierConvertible рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рдареАрдХ рдиреАрдЪреЗ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ Combine рдЗрд╕ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рд░реВрдк рд╣реИ -


 extension CustomCombineIdentifierConvertible where Self : AnyObject { public var combineIdentifier: CombineIdentifier { get } } 

рдЬреЛ рд╣рдореЗрдВ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рд╡реИрд░рд┐рдПрдмрд▓ CombIIdentifier рдХреА рдкрд░рд┐рднрд╛рд╖рд╛: CombineIdentifier рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдкреНрд░рджрд╛рди рдХреА рдЬрд╛рддреА рд╣реИ рдпрджрд┐ рдЗрд╕ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдкреНрд░рдХрд╛рд░ рднреА AnyObject рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдпрджрд┐ рдпрд╣ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╡рд░реНрдЧ рд╣реИред рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди рдПрдХ рд╡рд░реНрдЧ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЪрд░ рдкрд░рд┐рднрд╛рд╖рд╛ рдорд┐рд▓рддреА рд╣реИред


рдЕрдВрд╢рджрд╛рди


рдФрд░ рдЗрд╕рд▓рд┐рдП рд╣рдо рдЕрдкрдиреЗ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗред


 private final class FibonacciSubscription<S: Subscriber>: Subscription where S.Input == Int { var subscriber: S? var configuration: FibonacciConfiguration var count: Subscribers.Demand init(subscriber: S?, configuration: FibonacciConfiguration) { self.subscriber = subscriber self.configuration = configuration self.count = configuration.count } ... } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рдСрдирдлрд┐рдЧрд░реЗрд╢рди рдореЗрдВ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХрд╛ рдПрдХ рдордЬрдмреВрдд рд▓рд┐рдВрдХ рд╢рд╛рдорд┐рд▓ рд╣реИ, рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХрд╛ рдорд╛рд▓рд┐рдХ рд╣реИред рдпрд╣ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рд╣реИ, рд╕рдмреНрд╕рдХреНрд░рд┐рдкреНрд╢рди рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЗ рдкреНрд░рддрд┐рдзрд╛рд░рдг рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ, рдФрд░ рдЗрд╕реЗ рддрдм рддрдХ рдкрдХрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдм рддрдХ рдпрд╣ рдХрд╛рдо рдЦрддреНрдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рдпрд╛ рд░рджреНрдж рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред


рдЕрдЧрд▓рд╛, рд╣рдо рд░рджреНрджреАрдХрд░рдг рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕реЗ рд░рджреНрдж () рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред


 func cancel() { subscriber = nil } 

рд╢реВрдиреНрдп рдкрд░ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рд╕реЗрдЯ рдХрд░рдирд╛ рд╕рджрд╕реНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рджреБрд░реНрдЧрдо рдмрдирд╛рддрд╛ рд╣реИред


рдЕрдм рд╣рдо рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛ рднреЗрдЬрдиреЗ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред
рд╣рдо рдЕрдиреБрд░реЛрдз рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ (_: Subscribers.Demand)ред


 func request(_ demand: Subscribers.Demand) { // 1 guard count > .none else { subscriber?.receive(completion: .finished) return } // 2 count -= .max(1) subscriber?.receive(0) if count == .none { subscriber?.receive(completion: .finished) return } // 3 count -= .max(1) subscriber?.receive(1) if count == .none { subscriber?.receive(completion: .finished) return } // 4 var prev = 0 var current = 1 var temp: Int while true { temp = prev prev = current current += temp subscriber?.receive(current) count -= .max(1) if count == .none { subscriber?.receive(completion: .finished) return } } } 

1) рд╢реБрд░реБрдЖрдд рд╕реЗ, рд╣рдо рдпрд╣ рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рдХрд╛рд╢рдХ рдХрд┐рддрдиреЗ рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рде рд╣рдореЗрдВ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдпрджрд┐ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ, рддреЛ рднреЗрдЬрдиреЗ рд╡рд╛рд▓реЗ рдХреЛ рдкреВрд░рд╛ рдХрд░реЗрдВ рдФрд░ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рдПрдХ рд╕рдВрдХреЗрдд рднреЗрдЬреЗрдВ рдХрд┐ рдирдВрдмрд░ рднреЗрдЬрдиреЗ рдХрд╛ рдХрд╛рдо рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред
2) рдпрджрд┐ рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдПрдХ рдХреЗ рдмрд╛рдж рдЕрдиреБрд░реЛрдзрд┐рдд рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░реЗрдВ, рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рдЕрдиреБрдХреНрд░рдо рдХреЗ рдкрд╣рд▓реЗ рддрддреНрд╡ рдХреЛ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рднреЗрдЬреЗрдВ, рдЕрд░реНрдерд╛рддреН 0 рдФрд░ рдлрд┐рд░ рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рдХрд┐рддрдиреЗ рдФрд░ рддрддреНрд╡ рдкреНрд░рдХрд╛рд╢рдХ рд╣рдореЗрдВ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ, рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрдд рднреЗрдЬреЗрдВред ред
3) 2 рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╣реА рджреГрд╖реНрдЯрд┐рдХреЛрдг) рдкреИрд░рд╛, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдлрд┐рдмреЛрдирд╛рдЪреА рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рджреВрд╕рд░реЗ рддрддреНрд╡ рдХреЗ рд▓рд┐рдПред
4) рдпрджрд┐ 2 рд╕реЗ рдЕрдзрд┐рдХ рддрддреНрд╡реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдкрд░ рд╣рдо рдЕрдЧрд▓реЗ рдирдВрдмрд░ рдХреЛ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рдЕрдиреБрдХреНрд░рдо рд╕реЗ рд╕рдмрд╕реНрдХреНрд░рд╛рдЗрдмрд░ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рдпрд╣ рднреА рдЬрд╛рдВрдЪреЗрдВрдЧреЗ рдХрд┐ рдкреНрд░рдХрд╛рд╢рдХ рдЕрднреА рднреА рдХрд┐рддрдиреЗ рддрддреНрд╡ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдкреНрд░рдХрд╛рд╢рдХ рдЕрдм рдирдП рдирдВрдмрд░ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХрд╛ рд╕рдВрдХреЗрдд рднреЗрдЬреЗрдВред


рдлрд┐рд▓рд╣рд╛рд▓, рд╣рдордиреЗ рдРрд╕рд╛ рдХреЛрдб рд▓рд┐рдЦрд╛ рд╣реИ
 struct FibonacciConfiguration { var count: Subscribers.Demand } struct FibonacciPublisher: Publisher { typealias Output = Int typealias Failure = Never var configuration: FibonacciConfiguration func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input { let subscription = FibonacciSubscription(subscriber: subscriber, configuration: configuration) subscriber.receive(subscription: subscription) } } private final class FibonacciSubscription<S: Subscriber>: Subscription where S.Input == Int { var subscriber: S? var configuration: FibonacciConfiguration var count: Subscribers.Demand init(subscriber: S?, configuration: FibonacciConfiguration) { self.subscriber = subscriber self.configuration = configuration self.count = configuration.count } func cancel() { subscriber = nil } func request(_ demand: Subscribers.Demand) { // 1 guard count > .none else { subscriber?.receive(completion: .finished) return } // 2 count -= .max(1) subscriber?.receive(0) if count == .none { subscriber?.receive(completion: .finished) return } // 3 count -= .max(1) subscriber?.receive(1) if count == .none { subscriber?.receive(completion: .finished) return } // 4 var prev = 0 var current = 1 var temp: Int while true { temp = prev prev = current current += temp subscriber?.receive(current) count -= .max(1) if count == .none { subscriber?.receive(completion: .finished) return } } } } 

рдкрд╣рд▓реЗ рдкрд░реАрдХреНрд╖рдг


рдЕрдм рд╣рдо рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреНрдпрд╛ рд╣реИ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рдорд╛рд░рд╛ рдкреНрд░рдХрд╛рд╢рдХ рдФрд░ рд╕рджрд╕реНрдпрддрд╛ рд╣реИ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рд┐рдмреНрд╕реНрдХреНрд░рд╛рдЗрдмрд░ рдХреА рдХрдореА рд╣реИ, рдХреЙрдореНрдмрд┐рдиреЗрд╢рди рдмреЙрдХреНрд╕ рд╕реЗ 2 рд╕рд┐рдмреНрд╕реНрдХреНрд░рд╛рдЗрдмрд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рд╕рд┐рдВрдХ рдФрд░ рдЕрд╕рд╛рдЗрди рд╣реИред


  • рд╕рд┐рдВрдХ - рдпрд╣ рд╡рд┐рдзрд┐ рдПрдХ рдЧреНрд░рд╛рд╣рдХ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рддреБрд░рдВрдд рдЕрд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред
  • рдЕрд╕рд╛рдЗрди - рдкреНрд░рдХрд╛рд╢рдХ рд╕реЗ рд╡рд╕реНрддреБ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред

рд╕рд┐рдВрдХ рд╣рдорд╛рд░реЗ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЕрдиреБрдХреВрд▓ рд╣реИ, рдЗрд╕ рддрдереНрдп рдкрд░ рд╡рд┐рд╢реЗрд╖ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдпрд╣ рдЕрд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред


рдФрд░ рдпрд╣рд╛рдВ рд╣рдореЗрдВ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдВрддрд░ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЧрд┐рдирддреА рдЪрд░ рдореЗрдВ рд╣рдорд╛рд░рд╛ рдкреНрд░рдХрд╛рд╢рдХ рдЙрди рддрддреНрд╡реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╣рдорд╛рд░реЗ рдкреНрд░рдХрд╛рд╢рдХ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдпреЗ рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рд╕реНрд╡рдпрдВ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╣рдо рдЗрд╕ рд╡реИрд░рд┐рдПрдмрд▓ рдХреЗ рдмрд┐рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдЬрд▓реНрдж рд╣рдо рдкреНрд░рдХрд╛рд░ рдЗрдВрдЯ рдХреЗ рд╕реНрд╡реАрдХрд╛рд░реНрдп рдореВрд▓реНрдпреЛрдВ рдХреА рд╕реАрдорд╛ рд╕реЗ рдЖрдЧреЗ рдирд┐рдХрд▓ рдЬрд╛рдПрдВрдЧреЗред
рд╕рд┐рдВрдХ рдХреЗ рд╕рд╛рде рдорд╛рдорд▓рд╛ рдЕрд▓рдЧ рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рдХрд┐рддрдиреЗ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рд╕рд┐рдВрдХ рдЕрд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдорд╛рдиреЛрдВ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рддрдм рддрдХ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдпрд╣ рдкреВрд░рд╛ рд╣реЛрдиреЗ, рддреНрд░реБрдЯрд┐ рдпрд╛ рд░рджреНрдж рдХрд░рдиреЗ рдХрд╛ рд╕рдВрдХреЗрдд рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред


рд╣рдорд╛рд░реЗ рдкреНрд░рдХрд╛рд╢рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рдкреНрд░реЛрдЯреЛрдХреЛрд▓ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред


 extension Publishers { private static func fibonacci(configuration: FibonacciConfiguration) -> FibonacciPublisher { FibonacciPublisher(configuration: configuration) } static func fibonacci(count: Subscribers.Demand = .max(6)) -> FibonacciPublisher { FibonacciPublisher(configuration: FibonacciConfiguration(count: count)) } } 

рдФрд░ рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкреНрд░рдХрд╛рд╢рдХ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ


 Publishers.fibonacci(count: .max(10)) .sink { value in print(value, terminator: " ") } // print 0 1 1 2 3 5 8 13 21 34 - OK 

рдФрд░ рдЕрдм рд╕реАрдорд╛ рдорд╛рдорд▓реЗ


 Publishers.fibonacci(count: .max(1)) .sink { value in print(value, terminator: " ") } // prinst 0 - OK Publishers.fibonacci(count: .max(2)) .sink { value in print(value, terminator: " ") } // prints 0 1 - OK Publishers.fibonacci(count: .none) .print() //    publisher'a .sink { value in print(value, terminator: " ") } // prints receive finished - OK 

рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред


 Publishers.fibonacci(count: .unlimited) .print() .sink { value in print(value, terminator: " ") } // prints 0 1 1 2 3 5 8 13 21 ...   ,     Int. 

рдЖрдк .unlimited рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрдИ рдирдВрдмрд░реЛрдВ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВ? рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ .prefix (_) рдСрдкрд░реЗрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рд╕рдВрдЧреНрд░рд╣ рд╕реЗ .prefix (_) рдХреЗ рд╕рдорд╛рди рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдпрд╣ рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ N рддрддреНрд╡реЛрдВ рдХреЛ рдЫреЛрдбрд╝рддрд╛ рд╣реИред


 Publishers.fibonacci(count: .unlimited) .print() .prefix(5) .sink { _ in } // prints 0 1 1 2 3 cancel   ,       Int. 

рдХреНрдпрд╛ рд╕рдорд╕реНрдпрд╛ рд╣реИ? рд╢рд╛рдпрдж .prefix (_) рдореЗрдВ? рдЖрдЗрдП рдлрд╛рдЙрдВрдбреЗрд╢рди рд╕реЗ рдорд╛рдирдХ рдЕрдиреБрдХреНрд░рдо рдкрд░ рдереЛрдбрд╝рд╛ рдкреНрд░рдпреЛрдЧ рдХрд░реЗрдВред


 //   1 2 3 4 5 6 7 8 ... 1... .publisher .print() .prefix(5) .sink { _ in } // prints 1 2 3 4 5 cancel -  

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдиреЗ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рд╕рдорд╕реНрдпрд╛ рдкреНрд░рдХрд╛рд╢рдХ рдХреЗ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рд╣реИред
рд╣рдо .print () рд╕реЗ рд▓реЙрдЧ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ N рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдХреЗ рдмрд╛рдж .prefix (_) рд╕реЗ, рд╣рдо рдЕрдкрдиреЗ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди рдкрд░ рдХреИрдВрд╕рд┐рд▓ () рдХрд╣рддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдБ рд╣рдо рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЛ рд╢реВрдиреНрдп рдкрд░ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред


  func cancel() { subscriber = nil } 

рдпрджрд┐ рдЖрдк рдХреЙрд▓ рд╕реНрдЯреИрдХ рдЦреЛрд▓рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЧреНрд░рд╛рд╣рдХ рд╕реЗ рдХреЙрд▓ рдХреЗ рджреМрд░рд╛рди рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ () рдХреЛ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ (_ :), .Receive (_)ред рдЬрд┐рд╕рд╕реЗ рд╣рдо рдпрд╣ рдирд┐рд╖реНрдХрд░реНрд╖ рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рдордп рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░ (_ :) рдЧреНрд░рд╛рд╣рдХ рд╢реВрдиреНрдп рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд╣рдореЗрдВ рдирдП рдирдВрдмрд░ рдмрдирд╛рдиреЗ рдХреЗ рдХрд╛рдо рдХреЛ рд░реЛрдХрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕ рд╢рд░реНрдд рдХреЛ рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред


  func request(_ demand: Subscribers.Demand) { // 1 guard count > .none else { subscriber?.receive(completion: .finished) return } // 2 count -= .max(1) subscriber?.receive(0) guard let _ = subscriber else { return } // new if count == .none { subscriber?.receive(completion: .finished) return } // 3 count -= .max(1) subscriber?.receive(1) guard let _ = subscriber else { return } // new if count == .none { subscriber?.receive(completion: .finished) return } // 4 var prev = 0 var current = 1 var temp: Int while let subscriber = subscriber { // new temp = prev prev = current current += temp subscriber.receive(current) count -= .max(1) if count == .none { subscriber.receive(completion: .finished) return } } } 

рдЕрдм рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдХреЛ рдЪрд▓рд╛рдПрдВред


 Publishers.fibonacci(count: .unlimited) .print() .prefix(5) .sink { _ in } // prints 0 1 1 2 3 cancel -  

рдЕрдкреЗрдХреНрд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдорд┐рд▓рд╛ред


рдЧреНрд░рд╛рд╣рдХ


рдФрд░ рддреЛ рдФрд░ рдХреНрдпрд╛ рд╣рдорд╛рд░рд╛ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╢рдмреНрдЬ рддреИрдпрд╛рд░ рд╣реИ? рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВ, рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╣рдордиреЗ рдХреЗрд╡рд▓ рдПрдХ рд╕рд┐рдВрдХ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ рдЬреЛ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рдПрдХред рд╕реАрдорд╛рдВрдХрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдорд╛рдВрдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╣рдо рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдПрдХ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдХреБрдЫ рд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░реЗрдВрдЧреЗред рдХрдВрдмрд╛рдЗрди рдЗрд╕ рддрд░рд╣ рдХрд╛ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд▓реЗрдЦрди рд╕реЗ рдХреНрдпрд╛ рд░реЛрдХрддрд╛ рд╣реИ? рдиреАрдЪреЗ рд╣рдорд╛рд░реЗ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд╛рдЗрдмрд░ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред


 class FibonacciSubscriber: Subscriber { typealias Input = Int typealias Failure = Never var limit: Subscribers.Demand init(limit: Subscribers.Demand) { self.limit = limit } func receive(subscription: Subscription) { subscription.request(limit) } func receive(_ input: Input) -> Subscribers.Demand { .none } func receive(completion: Subscribers.Completion<Failure>) { print("Subscriber's completion: \(completion)") } } 

рдФрд░ рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд╛рдЗрдмрд░ рдХреЗ рдкрд╛рд╕ рдПрдХ рд╕реАрдорд╛ рд╕рдВрдкрддреНрддрд┐ рд╣реИ, рдЬреЛ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рдпрд╣ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХрд┐рддрдиреЗ рддрддреНрд╡реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИред рдФрд░ рдпрд╣ рдкреНрд░рд╛рдкреНрдд (_: рд╕рджрд╕реНрдпрддрд╛) рд╡рд┐рдзрд┐ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рд╣рдо рд╕рджрд╕реНрдпрддрд╛ рдХреЛ рдмрддрд╛рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдХрд┐рддрдиреЗ рддрддреНрд╡реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рднреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ (_: рдЗрдирдкреБрдЯ) -> рд╕рдмрд╕реНрдХреНрд░рд╛рдЗрдмрд░реНрд╕ред рдбрд┐рдорд╛рдВрдб рдлрд╝рдВрдХреНрд╢рди, рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдирдпрд╛ рдорд╛рди рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рд╣рдо рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдХрд┐рддрдиреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рддрддреНрд╡реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ: .none - рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ редmax (N) N рдореЛрд╣рд░реЗред , рдХреБрд▓ рдореЗрдВ, рдкреНрд░рд╛рдкреНрдд рддрддреНрд╡реЛрдВ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рд╛рдкреНрдд (_: рд╕рджрд╕реНрдпрддрд╛) рдореЗрдВ рднреЗрдЬреЗ рдЧрдП рд╕рджрд╕реНрдпрддрд╛ рдХреЗ рдореВрд▓реНрдп рдХреЗ рдпреЛрдЧ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдЧреА рдФрд░ рдкреНрд░рд╛рдкреНрдд рд╕реЗ рд╕рднреА рд░рд┐рдЯрд░реНрди рдорд╛рди (_: рдЗрдирдкреБрдЯ) -> Subscribers.Demandред


рджреВрд╕рд░рд╛ рдкрд░реАрдХреНрд╖рдг


рдЖрдЗрдП, рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд┐рдкреНтАНрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреЗрдЦреЗрдВред


 let subscriber = FibonacciSubscriber(limit: .max(3)) Publishers.fibonacci(count: .max(5)) .print() .subscribe(subscriber) // prints 0 1 1 2 3 -     0 1 1 

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкреНрд░рдХрд╛рд╢рдХ рдиреЗ 3 рдХреЗ рдмрдЬрд╛рдп 5 рдорд╛рди рднреЗрдЬреЗ рд╣реИрдВред рдРрд╕рд╛ рдХреНрдпреЛрдВ? рдЪреВрдБрдХрд┐ рдЕрдиреБрд░реЛрдз (_: Subscribers.Demand) рдХрд╛ рддрд░реАрдХрд╛ рдлрд╛рдЗрдмреЛрдиреИрдЪрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди рдХреА рд╡рд┐рдзрд┐ рдЧреНрд░рд╛рд╣рдХ рдХреА рдЬрд░реВрд░рддреЛрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рдирд╣реАрдВ рд░рдЦрддреА рд╣реИ, рддреЛ рдЗрд╕реЗ рдареАрдХ рдХрд░реЗрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдЕрдиреБрд░реЛрдз рдХреА рдЧрдИ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрдкрддреНрддрд┐ рдЬреЛрдбрд╝реЗрдВрдЧреЗ, рдЬрд┐рд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рдо рдЧреНрд░рд╛рд╣рдХ рдХреА рдЬрд░реВрд░рддреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░реЗрдВрдЧреЗред


 private final class FibonacciSubscription<S: Subscriber>: Subscription where S.Input == Int { var subscriber: S? var configuration: FibonacciConfiguration var count: Subscribers.Demand var requested: Subscribers.Demand = .none // new init(subscriber: S?, configuration: FibonacciConfiguration) { self.subscriber = subscriber self.configuration = configuration self.count = configuration.count } func cancel() { subscriber = nil } func request(_ demand: Subscribers.Demand) { guard count > .none else { subscriber?.receive(completion: .finished) return } requested += demand // new count -= .max(1) requested -= .max(1) // new requested += subscriber?.receive(0) ?? .none // new guard let _ = subscriber, requested > .none else { return } // new if count == .none { subscriber?.receive(completion: .finished) return } count -= .max(1) requested -= .max(1) // new requested += subscriber?.receive(1) ?? .none // new guard let _ = subscriber, requested > .none else { return } // new if count == .none { subscriber?.receive(completion: .finished) return } var prev = 0 var current = 1 var temp: Int while let subscriber = subscriber, requested > .none { // new temp = prev prev = current current += temp requested += subscriber.receive(current) // new count -= .max(1) requested -= .max(1) // new if count == .none { subscriber.receive(completion: .finished) return } } } } 

рддреАрд╕рд░рд╛ рдкрд░реАрдХреНрд╖рдг


 let subscriber = FibonacciSubscriber(limit: .max(3)) Publishers.fibonacci(count: .max(5)) .print() .subscribe(subscriber) // prints 0 1 1 - OK 

рдкреНрд░рдХрд╛рд╢рдХ рдЕрдм рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред


рдЕрдВрддрд┐рдо рдХреЛрдб
 import Foundation import Combine struct FibonacciConfiguration { var count: Subscribers.Demand } struct FibonacciPublisher: Publisher { typealias Output = Int typealias Failure = Never var configuration: FibonacciConfiguration func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input { let subscription = FibonacciSubscription(subscriber: subscriber, configuration: configuration) subscriber.receive(subscription: subscription) } } private final class FibonacciSubscription<S: Subscriber>: Subscription where S.Input == Int { var subscriber: S? var configuration: FibonacciConfiguration var count: Subscribers.Demand var requested: Subscribers.Demand = .none init(subscriber: S?, configuration: FibonacciConfiguration) { self.subscriber = subscriber self.configuration = configuration self.count = configuration.count } func cancel() { subscriber = nil } func request(_ demand: Subscribers.Demand) { guard count > .none else { subscriber?.receive(completion: .finished) return } requested += demand count -= .max(1) requested -= .max(1) requested += subscriber?.receive(0) ?? .none guard let _ = subscriber, requested > .none else { return } if count == .none { subscriber?.receive(completion: .finished) return } count -= .max(1) requested -= .max(1) requested += subscriber?.receive(1) ?? .none guard let _ = subscriber, requested > .none else { return } if count == .none { subscriber?.receive(completion: .finished) return } var prev = 0 var current = 1 var temp: Int while let subscriber = subscriber, requested > .none { temp = prev prev = current current += temp requested += subscriber.receive(current) count -= .max(1) requested -= .max(1) if count == .none { subscriber.receive(completion: .finished) return } } } } extension Publishers { private static func fibonacci(configuration: FibonacciConfiguration) -> FibonacciPublisher { FibonacciPublisher(configuration: configuration) } static func fibonacci(count: Subscribers.Demand = .max(6)) -> FibonacciPublisher { FibonacciPublisher(configuration: FibonacciConfiguration(count: count)) } } class FibonacciSubscriber: Subscriber { typealias Input = Int typealias Failure = Never var limit: Subscribers.Demand init(limit: Subscribers.Demand) { self.limit = limit } func receive(subscription: Subscription) { subscription.request(limit) } func receive(_ input: Input) -> Subscribers.Demand { .none } func receive(completion: Subscribers.Completion<Failure>) { print("Subscriber's completion: \(completion)") } } Publishers.fibonacci(count: .max(4)) .print() .sink { _ in } let subscriber = FibonacciSubscriber(limit: .max(3)) Publishers.fibonacci(count: .max(5)) .print() .subscribe(subscriber) 

рдкрд░рд┐рдгрд╛рдо


рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЗрд╕ рд▓реЗрдЦ рдиреЗ рдЖрдкрдХреЛ рдкреНрд░рдХрд╛рд╢рдХ, рд╕рджрд╕реНрдпрддрд╛ рдФрд░ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордЭ рдкреНрд░рджрд╛рди рдХреА рд╣реИ, рд╡реЗ рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдмрд╛рддрдЪреАрдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЬрдм рдЖрдк рдЕрдкрдиреЗ рдкреНрд░рдХрд╛рд╢рдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдХрд┐рди рдмрд┐рдВрджреБрдУрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рдХрд┐рд╕реА рднреА рдЯрд┐рдкреНрдкрдгреА, рд▓реЗрдЦ рдХреЗ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред

Source: https://habr.com/ru/post/hi482690/


All Articles