What's the difference between using or not using the 'where' clause with generics?
This is clearly stated in the Swift guide:
The requirements in a generic where clause specify that a type
parameter inherits from a class or conforms to a protocol or protocol
composition. Although the generic where clause provides syntactic
sugar for expressing simple constraints on type parameters (for
instance,<T: Comparable>
is equivalent to<T> where T: Comparable
and
so on), you can use it to provide more complex constraints on type
parameters and their associated types. For instance, you can constrain
the associated types of type parameters to conform to protocols. For
example,<S: Sequence> where S.Iterator.Element: Equatable
specifies
thatS
conforms to theSequence
protocol and that the associated type
S.Iterator.Element
conforms to theEquatable
protocol. This constraint
ensures that each element of the sequence is equatable.
Simply put, where
lets you specify constraints about the associated types of a generic parameter, while in <>
you can't do this.
Is there a practical difference between a type constraint on a generic type directly vs using a 'where' clause?
There is no difference. The first form
func testX<T>(value: T) where T: StringProtocol
was introduced with SE-0081 Move where clause to end of declaration to increase readability, in particular for longer lists of constraints. The rationale was to remove the where
clause out of the generic parameter list, for example
func foo<S: Sequence where S.Element == Int>(seq: S)
became
func foo<S: Sequence>(seq: S) where S.Element == Int
in Swift 3. As a side-effect, even simple constraints such as
your T: StringProtocol
can be moved to the newly introduced where-clause.
Why are where clauses only valid on functions with generic parameters?
Because ValueType
has nothing to do with this method (in the first example). It would be wrong to put such a method in a type (class
/struct
/enum
), since it's not really a true member of that type. It's conditionally a member of that type, depending on the truth value of the where
clause.
To achieve this, you would want to put this method in an extension of your type, with the where
clause you want. E.g.
extension YourType where ValueType == [String: Any] {
func version() throws -> String { ... }
}
Where clause in generic method
public static Expression<Func<BType, bool>> CastFunc<BType,IType>(Expression<Func<IType, bool>> customWhereClause) where BType : IType
Documentation "Constraints on Type Parameters": http://msdn.microsoft.com/en-us/library/d5x73970.aspx
Java generics vs C# where keyword
This is a very good article.
http://www.jprl.com/Blog/archive/development/2007/Aug-31.html
From that source
Java type and method constraints are specified using a "mini
expression language" within the '<' and '>' declaring the generic type
parameters. For each type parameter that has constraints, the syntax
is:TypeParameter ListOfConstraints
Where
ListOfConstraints
is a '&'-separated list of one of the
following constraints:
- Specifying a base class or implemented interface on the Generic
Type Argument by using: extends BaseOrInterfaceType
('&' must be used instead of ',' because ',' separates each generic
type parameter.)
C# generics: using class generic in where clause of method generic
Actually it is possible. This code compiles and runs just fine:
public class A<T>
{
public void Act<U>() where U : T
{
Console.Write("a");
}
}
static void Main(string[] args)
{
A<IEnumerable> a = new A<IEnumerable>();
a.Act<List<int>>();
}
What is not possible is using covariance / contravariance in generics, as explained here:
IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;
Related Topics
Checking If an Array of Custom Objects Contain a Specific Custom Object
Vertically Aligning Text in an Nstextfield Using Swift
Invalid Update: Invalid Number of Items in Section 0
What Does "Get" Mean in a Protocol's Property Declaration
Get an Array of Dates of the Current Week Starting on Monday
Child View Controller to Rotate While Parent View Controller Does Not
How to Reproduce This Xcode Blue Drag Line
Firebase Storage Downloadurl()' Is Deprecated: Use 'Storagereference.Downloadurlwithcompletion()
How to Get Start and End of the Week in Swift
How to Open Your App in Settings iOS 11
Value of Optional Type Cgfloat Not Unwrapped Error in Swift
Swift - Avaudioplayer, Sound Doesn't Play Correctly
Parameters After Opening Bracket
Why How to Use Codable with a Project Language Version of Swift 3.3