What's a placeholder? Why do we need to define placeholder data type for generics?
With credit to both answers provided.
Let's just say you wrote your code as below (without the <T>
) and see what happens:
func inspect (value1: T, value2: T) {
// some operation with value1, value2
}
What is the type of T
here? Is T
a class a struct or an enum? Or it's a generic type as you intended? The compiler doesn't know. It will give the following error:
error: use of undeclared type 'T'
Just because you wrote something with T
it's not going to magically transform into a generic.
To better illustrate the problem see this snippet:
func inspect (value1: T, value2: T) {
// some operation with value1, value2
var x = T()
var m = U()
}
class T {
var name = "someName"
}
class U {
var name = "someName"
}
var x = T()
<-- Do you expect this to be an instance of class T
or a generic type?
Without <T>
, x
is expected to be an instance of type T
. If you haven't defined T
as a type, if not then you'd just get an error.
Which is why in real code you see using <T>
. The actual type will come into the 'place' where type T
was 'holding' onto before. :
func inspect <T> (value1: T, value2: T) {
// some operation with value1, value2
var x = T() // error!
var m = U() // No error
}
class T {
var name = "someName"
}
class U {
var name = "someName"
}
Actually doing x = T()
creates an error:
'T' cannot be constructed because it has no accessible initializers
If this error wasn't spotted by the compiler then the T
inside the function would be non-generic and would come from the class definition or just unknown...
The reason we do <T>
is to create a local vanilla type and avoid having wrong expectations from outside. (Though if you constrain it, then it's different)
Why does Swift supersede the generic T
over the class T
? I assume it's because Swift gives priority to the local scope.
In java what's the difference between ?, E, T
I'm assuming you're talking about Generics. The 'E' and 'T' are placeholders and can be used interchangeably in class definitions. By convention 'E' is an Element and 'T' is a Type. The question mark is a placeholder for an unknown type. You often see things like this:
List<? extends MyObject> x;
This implies that 'x' is a list of objects that are subclasses of MyObject, but we don't know what they are exactly.
See: http://docs.oracle.com/javase/tutorial/java/generics/genTypes.html
In java, what is the exact meaning of each type parameter of a generic method in a type introduction?
It's hard to understand what exactly you're asking and what exactly you are confused about; I'll try answering your questions anyway.
Type parameters are placeholders for actual types, no matter whether you use them on a class or on a method. Note that this is exactly the same idea as with regular value parameters: they are placeholders for actual values that you supply when you call a method.
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2)
This is a method with two type parameters, K
and V
, and two value parameters, p1
and p2
.
When you call this method, you'll have to specify actual types for the type parameters, and actual values for the value parameters. In other words: you'll have to specify what types K
and V
are and you'll have to pass two instances of class Pair
for p1
and p2
.
The type parameters are "passed" to the type Pair
in this example. So, the declaration of method compare
means: I have a method named compare
which takes two Pair
objects with type parameters K
and V
. Instead of specifying actual, concrete types, I leave those as parameters. By doing this, you can call compare
with any Pair
with specific types for K
and V
.
For example, you can call compare
with two Pair<Integer, String>
objects. Or two Pair<BigDecimal, Long>
objects, etc.
Are they placeholders for individual arguments passed into the method?
They are placeholders for types, just like regular parameters are placeholders for values.
Are they placeholders for type parameters passed to the actual object-type arguments passed into the method(i.e. Pair<K, V> //I view this as one unique type: class Pair<K, V> that receives two unique type parameters, K and V)?
Yes... (if I understand your question correctly). The method signature means that the method takes two Pair<K, V>
objects, where you leave specifying the actual types to use for K
and V
to the caller of the method.
Or do generic methods require a unique type parameter for every variable they access whether they are passed as arguments to the method or arguments to an object, which is then passed into the method?
I don't understand what you mean by this question.
Typescript Placeholder Generic
Not sure, if I understood your use-case.
Maybe you just want to introduce a new type for all your attributes e.g.
type MyAttributes = A | B | C;
type MyDataType<T extends MyAttributes> = {
name: string;
age: number;
attributes: T
}
interface ForMyGeneralComponent{
data: MyDataType<MyAttributes>
}
How to use Extract on a Generic placeholder
The main problem is that when T
is an unresolved generic type parameter, the compiler does not (as of TS3.5 anyway) perform the sort of type analysis it would need to in order to recognize that "bar"
is assignable to Extract<keyof T, string>
even when T
is constrained to extend IAttrs
. Extract
is a conditional type, and the compiler generally defers most analysis of unresolved conditional types. Perhaps this particular use case could be filed in GitHub as a suggestion, but I doubt it would be given priority.
So we need to either use a resolved conditional type, or we need to use the unresolved type parameter in a non-conditional type.
Resolved conditional type: Since
keyof T
includes all ofkeyof IAttrs
, the typekeyof T
is equivalent tokeyof T | keyof IAttrs
. SoExtract<keyof T | keyof IAttrs, string>
is equivalent to the problematic type. But sinceExtract
is distributive, it will be evaluated asExtract<keyof T, string> | Extract<keyof IAttrs, string>
. The rightmost constituent is a resolved conditional type which will be eagerly evaluated to be just"bar"
. So now we haveExtract<keyof T, string> | "bar"
. The unresolved conditional type is still there, but now"bar"
is explicitly part of the union... and the error should go away.Unresolved non-conditional type: The
Extract
type was introduced in TS2.8 with conditional types. It filters a union type with a constraint. Before TS2.8 if we wanted to constrain a type like that, we just had to use intersections. It also used to be that intersections over unions were messy, and("foo" | "bar") & ("bar" | "baz")
would evaluate to("foo" & "bar") | ("foo" & "baz") | "bar" | ("bar" & "baz")
. Nowadays though it gets reduced to just"bar"
, as desired. And luckily, even unresolved type parameters are analyzed in intersections... that is, ifX
is known to be assignable to bothA
andB
, thenX
is known to be assignable toA & B
. So we can changeExtract<keyof T, string>
to(keyof T) & string
and the error should also go away.
Let's look at some modified code that does both things:
class Foo<T> {
// intersection
get(a: keyof T & string) {
return "";
}
}
interface IAttrs {
bar: boolean;
}
class Bar<T extends IAttrs> extends Foo<T> {
constructor() {
super();
this.get("bar");
this.get2("bar");
}
// resolved conditional
get2(a: Extract<keyof T | keyof IAttrs, string>) {
return "";
}
}
class FooBar extends Foo<IAttrs> {
constructor() {
super();
this.get("bar");
}
}
Playground link
And that all compiles with no error. Okay, hope that helps; good luck!
Current Type placeholder in C# generic types?
Make the interface generic:
public class MySpecialCollection<T> where T : ISomething<T> {
...
}
public interface ISomething<T> {
T NextElement { get; }
T PreviousElement { get; }
}
public class XSomething : ISomething<XSomething> {
...
}
Related Topics
Query Value Between Two Other Values in Firebase
Updating Existing Constraints Does Not Work, Wrong Use of .Active Property
How to Create a UIprintpaper to Test UIprintinteractioncontrollerdelegate
Connect Physicsbodies on Tilemap in Spritekit
How to Use Protocols for Stucts to Emulate Classes Inheritance
What's The How to Access a Swift Package Item from Objective-C
Why I Can't Convert String to Date in Swift
Siri Remote's Menu Button Not Exiting Application When UIbutton Is Focused
How to Draw Something on a PDF in Swift
Back to Table View from Detail Page Without Reload, Swift
<= Is Not a Prefix Unary Operator
How to Decorate Siesta Request with an Asynchronous Task
Animate Line Under One Button to Another
Swift Coredata: Unable to Section Tableview Using Sectionnamekeypath with Custom Function