I am constantly getting the: Undeclared identifier for an interface type I have defined in another unit.
Here is what I have:
unit Drawers;
interface
implementation
type
IDrawer = interface
['{070B4742-89C6-4A69-80E2-9441F170F876}']
procedure Draw();
end;
end.
unit Field;
interface
uses
Graphics, Classes, Drawers;
TField = class(TInterfacedObject, IField)
private
FSymbolDrawer: IDrawer;
At FSymbolDrawer I get the complier error.
Of course I have the uses Drawers; in the unit where TField is defined.
What's this about?
Thank you
In the unit Drawers the type declaration of IDrawer has to be in the interface part of the unit. You have inserted it in the implementation part where it is only visible for in-unit declarations.
Here is the code:
unit Drawers;
interface
type
IDrawer = interface
['{070B4742-89C6-4A69-80E2-9441F170F876}']
procedure Draw();
end;
implementation
end.
Which uses clause do you add Drawers to? It has to be in the interface uses clause (above the definition of TField that uses it).
Related
I am reading Kotlin in Action 2nd edition.
Chapter 3 says:
If the class has a member function with the same signature as an extension function, the member function always takes precedence
At the same the book demonstrates the CharSequence.split Kotlin's stdlib extension function (which API is less confusing than an API of Java's String#split).
The thing I do not understand is how this split extension functions takes precedence on the following call:
"12.345-6.A".split(".") // <-- Kotlin's extension function gets invoked here even though there is a member function on String class in Java with matching signature
The book also leaves the following comment on this case:
Kotlin hides the confusing method and provides as replacements several overloaded extensions named split that have different arguments
How does Kotlin hide a member function? Can I also shadow some member function which I do not like with my custom extension function? Or it is a trick which is only available to Kotlin language developers?
Actually Kotlin has a separate implementation of CharSequence and String.
These kotlin String/Charsequence does not have its split function. Kotlin team has made all those string implementation functions separately with help of extension functions.Your string will be referring to kotlin String instead of Java String.
If you need to create java String, you need to refer String with package like below.
var str : java.lang.String = java.lang.String("a b c")
str.split("")
Here it will always call Java split function.
Even if you create split function for java.lang.String , it will call only member function as you have read.
member function always takes precedence
This question already has answers here:
Why is the type not accessible?
(2 answers)
Closed 6 years ago.
Using cygwin64 on Windows this program won't compile:
program test
implicit none
!define my type
type myType
real::foo
integer::bar
end type myType
!define an operator for this type
interface operator (>)
logical function compare(a,b)
type(myType),intent(in) :: a,b
compare = a%foo>b%foo
end function compare
end interface operator (>)
!simple example of operator usage
type(myType) :: tfoo, tbar
tfoo = card(1.,2); tbar = card(3.,4)
print*, tfoo>tbar
end program test
gfortran (only argument is "std=f2008") tells me:
type(myType),intent(in) :: a,b
1
Error: Derived type ‘mytype’ at (1) is being used before it is defined
which is confusing to me, since the type is defined right before the operator. I'm relatively new to Fortran, so this example code might have some more errors.
The same problem occurred here, but encapsulating myType in a separate module did not resolve the issue.
There are several issues with your code, but this particular error is because myType is in the host scope, but not in the interface block. The solution is to either place the derived type in a separate module as suggested in the linked thread, or import the derived type from the host scoping unit:
interface operator (>)
logical function compare(a,b)
import myType
type(myType),intent(in) :: a,b
end function compare
end interface operator (>)
This is described in the Fortran 2008 Standard, Cl. 12.4.3.3 "IMPORT statement":
1 The IMPORT statement specifies that the named entities from the host scoping unit are accessible in the interface
body by host association. An entity that is imported in this manner and is defined in the host scoping unit shall be
explicitly declared prior to the interface body.
An interface block may not have executable statements included - so the assignment you have there is not valid. Furthermore, card is not defined in your code.
I would like to have my own implementation of an existing module but to keep a compatible interface with the existing module. I don't have a module type for the existing module, only an interface. So I can't use include Original_module in my interface. Is there a way to get a module type from an interface?
An example could be with the List module from the stdlib. I create a My_list module with exactly the same signature than List. I could copy list.mli to my_list.mli, but it does not seem very nice.
In some cases, you should use
include module type of struct include M end (* I call it OCaml keyword mantra *)
rather than
include module type of M
since the latter drops the equalities of data types with their originals defined in M.
The difference can be observed by ocamlc -i xxx.mli:
include module type of struct include Complex end
has the following type definition:
type t = Complex.t = { re : float; im : float; }
which means t is an alias of the original Complex.t.
On the other hand,
include module type of Complex
has
type t = { re : float; im : float; }
Without the relation with Complex.t, it becomes a different type from Complex.t: you cannot mix code using the original module and your extended version without the include hack. This is not what you want usually.
You can look at RWO : if you want to include the type of a module (like List.mli) in another mli file :
include (module type of List)
I am currently writing a wrapper for a native C++ class in CLI/C++. I am on a little GamePacket class at the moment. Consider the following class:
public ref class GamePacket
{
public:
GamePacket();
~GamePacket();
generic<typename T>
where T : System::ValueType
void Write(T value)
{
this->bw->Write(value);
}
};
I want that I'm able to call the function as following in C#, using my Wrapper:
Packet.Write<Int32>(1234);
Packet.Write<byte>(1);
However, I can't compile my wrapper. Error:
Error 1 error C2664: 'void System::IO::BinaryWriter::Write(System::String ^)' : cannot convert argument 1 from 'T' to 'bool'
I don't understand this error, where does the System::String^ comes from. I'm seeing a lot of overloads of the Write() method, does CLI/C++ not call the correct one, and if so, how can I make it call the correct one?
Reference MSDN: http://msdn.microsoft.com/en-us/library/system.io.binarywriter.write(v=vs.110).aspx
Templates and generics don't work the same.
With templates, the code gets recompiled for each set of parameters, and the results can be pretty different (different local variable types, different function overloads selected). Specialization makes this really powerful.
With generics, the code only gets compiled once, and the overload resolution is done without actually knowing the final parameters. So when you call Write(value), the only things the compiler knows is that
value can be converted to Object^, because everything can
value derives from ValueType, because your constraint tells it
Unfortunately, using just that information, the compiler can't find an overload of Write that can be used.
It seems like you expected it to use Write(bool) when T is bool, Write(int) when T is int, and so on. Templates would work like that. Generics don't.
Your options are:
a dozen different copies of your method, each of which has a fixed argument type that can be used to select the right overload of BinaryWrite::Write
find the overload yourself using reflection, make a delegate matching the right overload, and call it
use expression trees or the dynamic language runtime to find and make a delegate matching the right overload, and then you call it
Dart Editor version 1.2.0.release (STABLE). Dart SDK version 1.2.0.
This source code produces runtime exception.
void main() {
test(new Base());
}
void test(Child child) {
}
class Base {
}
class Child extends Base {
}
I assumed that the analyzer generates something like this.
The argument type 'Base' cannot be assigned to the parameter type 'Child'
But I can only detect this error at runtime when occurred this exception (post factum).
Unhandled exception:
type 'Base' is not a subtype of type 'Child' of 'child'.
The analyzer is following the language specification here.
It only warns if a the static type of the argument expression is not assignable to the type of function the parameter.
In Dart, expressions of one type is assignable to variables of another type if either type is a subtype of the other.
That is not a safe type check. It does not find all possible errors. On the other hand, it also does not disallow some correct uses like:
Base foo = new Child();
void action(Child c) { ... }
action(foo); // Perfectly correct code at runtime.
Other languages have safe assignment checks, but they also prevent some correct programs. You then have to add (unsafe/runtime checked) cast operators to tell the compiler that you know the program is safe. It's a trade-off where Dart has chosen to be permissive and avoid most casts.
Let's try to be polite and answer the question without any prejudice.
I think I understand what you expected and here my angle on what the error means:
You are invoking the method with the argument of type Base
The method is expecting an argument of type Child
The Child is not equal to the Base, neither is a subtype of it (as a fact it is the Child that is a subtype of the Base)
It is working as expected as it makes only sense to provide object of the expected type (or it's subtypes - specialisations).
Update:
After reading again your question I realised that you are pointing out that editor is not finding the type problem. I assume this is due to the point that Dart programs are dynamic and hence certain checks are not done before the runtime.
Hope it helps ;-)