Ifyou are running the same PC for a number of years you will eventually notice an increase in duplicate files on the system. This is especially the case if you like to download files in bulk from the Internet, for instance big image archives or music archives. While you can sort the collection manually it may have grown to a size that you can't manage manually anymore. Comparing all images of a collection of 50,000 or more images is something that would take a long time.
Software like Noclone automates the process, and while the free version is limited in the number of files it can check in one go, it is an efficient and fast program that you can use for that purpose.
All versions of the program use the same setup file which can be confusing at first. Just download the program to your system and select free edition during setup. The program opens the search configuration on start. Here you can select some, but not all options as some are limited to the commercial versions of the application.
The features enabled in the free version are scanning a folder and all of its subfolders for duplicate files, duplicate mp3s, similar files or duplicate Outlook emails. The options to compare folders and to find similar images are not available in the free version.
Once you have made that selection and picked a root folder, you can click on the search button to start the scan. Depending on the data set and performance of the PC, it may take a while to complete. The similar files option for instance takes a lot longer to complete than the exact duplicate files or duplicate mp3 scan.
You now need to mark files that you want to remove. You can't use the Smart Marker option as it is limited to commercial versions. While it may take a while to pick all the files for deletion, it is still faster than comparing the files manually on your system.
The program displays notifications about the free version on exit and start of the program. It in addition highlights that before scans, and when you try to use a program feature that is limited to a paid version. That's certainly overkill and bound to drive many users away from the program. If you do not mind that, for instance because you intend to run it once every couple of months or so, you will come to the conclusion that it is a fast efficient duplicate file finder for Windows.
This software sounds OK, but there are a lot of better options. For example, Easy Duplicate Finder is a really powerful program with lots of features for music and photos (iTunes synch, iPhoto compatibility, etc) and it works on both Windows and Mac. Plus its trial scans for all duplicates on your computer and even though you can only delete a limited number with the trial version, you will always know exactly where and what they are. The scans are free for a liftetime.
I just extracted the noclone.exe download. It consists of a setup.exe file and a NoClone4EntSetup.msi file. This latter file extract into a 14.2 mb directory of 58 files and 11 folders. The dll files are way too numerous to mention. There is one interesting file called toolbarinstall.bat. The bat file contents are:
The solution is to instead introduce your own clone method, properly returning a trait object. You can even implement it automatically for everything that's Clone, you just need to make that explicit.
You'll probably want to mess with this a bit to get the exact semantics you want, but it's possible. The trick is that the compiler won't do any autobatic boxing for you - it won't turn T into Box automatically in clone(). You have to write the code which does that yourself.
When we create Box, DogT is unsized. Fro here on out I'll use the new nomenclature dyn DogT to refer to this unsized dynamic trait. There can't exist a value of dyn DogT on the stack because it could be any number of different strict, all with different sizes, and the stack needs fixed sized values.
Your original code works without DogT: Clone specifically because you have a value Box, not dyn DogT. The box has a fixed size, and the dynamic size is hidden in an allocation. dyn DogT: Clone would similarly fail because you would need a single concrete function ::clone which returns a dyn DogT. But dyn DogT cannot exist without a box or other indirection because it does not have a fi ed size. Thus this function cannot exist.
I focused on Box::clone because while it doesn't exist, a function like it could. Since it would return a Box, not a raw dyn DogT, the return value could actually exist on the stack and the definition could work.
If you haven't read it already, this book chapter section will probably be helpful? Advanced Types - The Rust Programming Language. It doesn't talk about sized in relation to traits but it might give some background knowledge in a more structured way than I can present it.
I come from a background of C, C++, Clojure, Kotlin. I typed in all the examples in "Rust by Example" , switched over to Rust, and started asking questions in this forum. I have not read the "Rust Book"
dyn DogT: Clone would similarly fail because you would need a single concrete function ::clone which returns a dyn DogT . But dyn DogT cannot exist without a box or other indirection because it does not have a fi ed size. Thus this function cannot exist.
The last missing piece, I think, is that rust has a requirement dyn DogT: DogT. All methods usable on T: DogT must be usable on dyn DogT unless they are explicitly excluded with where Self: Sized. So if DogT: SomeTrait, then dyn DogT: SomeTrait as well.
I was about to ask why we can't just add where Self: Sized, but I realized midway:
If trait B requires where Self: Sized + Clone, then it implies that B is going to, at some point, use self.clone(), which in context of trait B returns a dyn B, while to anyone else a struct C which impl B for C will return a C which is Sized, so even if we were to add a Sized restraint to Self, we wouldn't be able to do anything with it, because either way Self is !Sized in the eyes of a trait object because there may be different types that impl B for MyStruct and not all of them will have the same size
(Sorry if it's convoluted, I might've gotten a bit carried away)
But I know that would make the type system much more complicated, and make ensuring backwards compatibility much harder if it were allowed for things besides Sized (same reason we don't have a where Self: !Trait bound).
I hadn't thought about this before, but it seems like there's an interesting concept of "dynamic cloneability" here: i.e., we want to be able to deep-copy objects via dynamic references. The Clonable/CloneDyn trait above seems like a reasonable way to represent it, but the use of Box seems overly restrictive; all that we want is for there to be some way to create a new trait object deep-copied from an existing one.
It seems like representing this in a usefully generic way probably isn't possible without some extra language features, though, such as placement-new and/or some stable way of dealing with unsized types.
3a8082e126